aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.classpath2
-rw-r--r--make/build-common.xml12
-rw-r--r--make/build-jogl.xml34
-rw-r--r--make/build.xml2
-rw-r--r--src/jogl/classes/com/jogamp/opengl/av/GLMediaEventListener.java17
-rw-r--r--src/jogl/classes/com/jogamp/opengl/av/GLMediaPlayer.java90
-rw-r--r--src/jogl/classes/com/jogamp/opengl/av/GLMediaPlayerFactory.java18
-rw-r--r--src/jogl/classes/com/jogamp/openmax/OMXEventListener.java14
-rw-r--r--src/jogl/classes/com/jogamp/openmax/OMXInstance.java509
-rw-r--r--src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java195
-rw-r--r--src/jogl/classes/jogamp/opengl/av/EGLMediaPlayerImpl.java109
-rw-r--r--src/jogl/classes/jogamp/opengl/av/GLMediaPlayerImpl.java307
-rw-r--r--src/jogl/classes/jogamp/opengl/omx/OMXGLMediaPlayer.java238
-rw-r--r--src/jogl/native/openmax/jogamp.opengl.omx.OMXGLMediaPlayer.c (renamed from src/jogl/native/openmax/com_sun_openmax_OMXInstance.c)33
-rw-r--r--src/jogl/native/openmax/omx_tool.c6
-rw-r--r--src/jogl/native/openmax/omx_tool.h2
-rwxr-xr-xsrc/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java373
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/moviesimple.fp21
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/moviesimple.vp22
19 files changed, 1450 insertions, 554 deletions
diff --git a/.classpath b/.classpath
index bb012ba81..064f05938 100644
--- a/.classpath
+++ b/.classpath
@@ -31,6 +31,6 @@
<classpathentry combineaccessrules="false" kind="src" path="/gluegen"/>
<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Ant"/>
<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/SWT"/>
- <classpathentry kind="lib" path="/gluegen/make/lib/android-sdk/9/android.jar" sourcepath="/gluegen/make/lib/android-sdk/9/android-java-src.zip"/>
+ <classpathentry kind="lib" path="/gluegen/make/lib/android-sdk/15/android.jar" sourcepath="/gluegen/make/lib/android-sdk/15/android-java-src.zip"/>
<classpathentry kind="output" path="build/eclipse-classes"/>
</classpath>
diff --git a/make/build-common.xml b/make/build-common.xml
index c18cf89b4..dfe38a676 100644
--- a/make/build-common.xml
+++ b/make/build-common.xml
@@ -287,6 +287,7 @@
<property name="jogl.os.x11.jar" value="${build.jogl}/jogl.os.x11.jar" />
<property name="jogl.os.win.jar" value="${build.jogl}/jogl.os.win.jar" />
<property name="jogl.os.osx.jar" value="${build.jogl}/jogl.os.osx.jar" />
+ <property name="jogl.os.android.jar" value="${build.jogl}/jogl.os.android.jar" />
<property name="jogl.gldesktop.jar" value="${build.jogl}/jogl.gldesktop.jar" />
<property name="jogl.gldesktop.dbg.jar" value="${build.jogl}/jogl.gldesktop.dbg.jar" />
<property name="jogl.glugldesktop.jar" value="${build.jogl}/jogl.glu.gldesktop.jar" />
@@ -343,6 +344,17 @@
<pathelement location="${jogl.util.fixedfuncemu.jar}" />
<pathelement location="${jogl.omx.jar}" />
</path>
+ <path id="jogl_all-android_atoms.classpath">
+ <pathelement location="${jogl.core.jar}" />
+ <pathelement location="${jogl.glmobile.jar}" />
+ <pathelement location="${jogl.glmobile.dbg.jar}" />
+ <pathelement location="${jogl.util.jar}" />
+ <pathelement location="${jogl.glutess.jar}" />
+ <pathelement location="${jogl.glumipmap.jar}" />
+ <pathelement location="${jogl.util.fixedfuncemu.jar}" />
+ <pathelement location="${jogl.os.android.jar}" />
+ <pathelement location="${jogl.omx.jar}" />
+ </path>
<!--
${jogl.core.jar} ${jogl.glutess.jar} ${jogl.glumipmap.jar} ${jogl.glugldesktop.jar} ${jogl.os.x11.jar} ${jogl.os.win.jar} ${jogl.os.osx.jar} ${jogl.gldesktop.jar} ${jogl.gldesktop.dbg.jar} ${jogl.glmobile.jar} ${jogl.glmobile.dbg.jar} ${jogl.omx.jar} ${jogl.util.jar} ${jogl.util.gldesktop.jar} ${jogl.util.awt.jar} ${jogl.util.fixedfuncemu.jar} ${jogl.sdk.jar} -->
diff --git a/make/build-jogl.xml b/make/build-jogl.xml
index 875fba709..ace272b74 100644
--- a/make/build-jogl.xml
+++ b/make/build-jogl.xml
@@ -108,7 +108,7 @@
value="jogamp/opengl/glu/gl2/** jogamp/opengl/glu/nurbs/** jogamp/opengl/glu/registry/** javax/media/opengl/glu/gl2/**"/>
<property name="java.part.openmax"
- value="com/jogamp/openmax/** jogamp/openmax/**"/>
+ value="jogamp/opengl/omx/**"/>
<property name="java.part.sdk"
value="com/jogamp/opengl/util/glsl/sdk/**"/>
@@ -122,6 +122,9 @@
<property name="java.part.cgl"
value="jogamp/opengl/macosx/cgl/*"/>
+ <property name="java.part.android"
+ value="jogamp/opengl/android/**"/>
+
<property name="java.part.gldesktop"
value="jogamp/opengl/**/gl2/** jogamp/opengl/**/gl3/** jogamp/opengl/**/gl4/**"/>
@@ -173,6 +176,9 @@
<property name="java.part.util.fixedfuncemu.shadercode"
value="jogamp/opengl/util/glsl/fixedfunc/shaders/* jogamp/opengl/util/glsl/fixedfunc/shaders/bin/**"/>
+ <property name="java.part.util.av"
+ value="com/jogamp/opengl/av/** jogamp/opengl/av/**"/>
+
<property name="java.part.nonjava"
value="${java.part.util.fixedfuncemu.shadercode} ${java.part.util.graph.shadercode} ${java.part.util.graph.fonts}"/>
@@ -191,13 +197,20 @@
<isset property="setup.noSWT"/>
</condition>
+ <condition property="java.excludes.android"
+ value="${java.part.android}">
+ <not>
+ <isset property="isAndroid"/>
+ </not>
+ </condition>
+
<property name="java.excludes.javadoc.packagenames"
value="jogamp.opengl.gl2.fixme.*,com.jogamp.audio.windows.waveout.TestSpatialization"/>
<property name="java.excludes.fixme"
value="jogamp/opengl/gl2/fixme/** com/jogamp/audio/windows/waveout/TestSpatialization.java" />
- <property name="java.excludes.all" value="${java.excludes.fixme} ${java.excludes.awt} ${java.excludes.swt}" />
+ <property name="java.excludes.all" value="${java.excludes.fixme} ${java.excludes.awt} ${java.excludes.swt} ${java.excludes.android}" />
<echo message="java.excludes.all: ${java.excludes.all}" />
</target>
@@ -1356,7 +1369,7 @@
<!-- FIXME: the Mixer should be moved to another library -->
<!--include name="${rootrel.src.c}/Mixer.cpp" if="isWindows"/-->
<include name="${rootrel.src.c.openmax}/omx_tool.c" if="setup.addNativeOpenMAX"/>
- <include name="${rootrel.src.c.openmax}/com_jogamp_openmax_OMXInstance.c" if="setup.addNativeOpenMAX"/>
+ <include name="${rootrel.src.c.openmax}/jogamp_opengl_omx_OMXGLMediaPlayer.c" if="setup.addNativeOpenMAX"/>
<include name="${rootrel.generated.c.jogl}/gl4/GL4bcImpl_JNI.c"/>
<!--include name="${rootrel.generated.c.jogl}/GLU_JNI.c"/ EMPTY -->
@@ -1372,7 +1385,7 @@
<include name="${rootrel.src.c}/GLDebugMessageHandler.c"/>
<include name="${rootrel.src.c}/GLXGetProcAddressARB.c" if="isX11"/>
<include name="${rootrel.src.c.openmax}/omx_tool.c" if="setup.addNativeOpenMAX"/>
- <include name="${rootrel.src.c.openmax}/com_jogamp_openmax_OMXInstance.c" if="setup.addNativeOpenMAX"/>
+ <include name="${rootrel.src.c.openmax}/jogamp_opengl_omx_OMXGLMediaPlayer.c" if="setup.addNativeOpenMAX"/>
<include name="${rootrel.generated.c.jogl}/egl/EGL_JNI.c"/>
<include name="${rootrel.generated.c.jogl}/egl/EGLExtImpl_JNI.c"/>
@@ -1466,7 +1479,7 @@
</macrodef>
<target name="c.build.jogl.prepare.openMAX" if="setup.addNativeOpenMAX">
- <javah destdir="${src.generated.c.openmax}" classpath="${javah.classpath}" class="com.jogamp.openmax.OMXInstance" />
+ <javah destdir="${src.generated.c.openmax}" classpath="${javah.classpath}" class="jogamp.opengl.omx.OMXGLMediaPlayer" />
</target>
<target name="c.build.jogl.prepare" depends="c.build.jogl.prepare.openMAX">
@@ -1554,6 +1567,12 @@
</jar>
</target>
+ <target name="build-jars-android" depends="setup-manifestfile" if="isAndroid">
+ <jar manifest="${build.jogl}/manifest.mf" destfile="${jogl.os.android.jar}" filesonly="true">
+ <fileset dir="${classes}" includes="${java.part.android}"/>
+ </jar>
+ </target>
+
<target name="build-jars-mobile-javase" depends="setup-manifestfile">
<jar manifest="${build.jogl}/manifest.mf" destfile="${jogl.glmobile.jar}" filesonly="true">
<fileset dir="${classes}"
@@ -1608,7 +1627,8 @@
</jar>
</target>
- <target name="build-jars-javase" depends="setup-manifestfile, build-jars-mobile-javase, build-jars-desktop-javase, build-jars-awt-javase, build-jars-swt-javase">
+ <target name="build-jars-javase" depends="setup-manifestfile, build-jars-android, build-jars-mobile-javase,
+ build-jars-desktop-javase, build-jars-awt-javase, build-jars-swt-javase">
<jar manifest="${build.jogl}/manifest.mf" destfile="${jogl.core.jar}" filesonly="true">
<fileset dir="${classes}"
includes="${java.part.core}"
@@ -1628,7 +1648,7 @@
</jar>
<jar manifest="${build.jogl}/manifest.mf" destfile="${jogl.util.jar}" filesonly="true">
<fileset dir="${classes}"
- includes="${java.part.util} ${java.part.util.glsl} ${java.part.util.graph}"
+ includes="${java.part.util} ${java.part.util.glsl} ${java.part.util.graph} ${java.part.util.av}"
excludes="${java.part.util.awt} ${java.part.util.gldesktop} ${java.part.util.fixedfuncemu}"/>
</jar>
<jar manifest="${build.jogl}/manifest.mf" destfile="${jogl.util.fixedfuncemu.jar}" filesonly="true">
diff --git a/make/build.xml b/make/build.xml
index 203132816..24670fcce 100644
--- a/make/build.xml
+++ b/make/build.xml
@@ -103,7 +103,7 @@
<archives>
<zips>
<path refid="nativewindow_core_atoms.classpath"/>
- <path refid="jogl_all-mobile_atoms.classpath"/>
+ <path refid="jogl_all-android_atoms.classpath"/>
<path refid="newt_all-android_atoms.classpath"/>
</zips>
</archives>
diff --git a/src/jogl/classes/com/jogamp/opengl/av/GLMediaEventListener.java b/src/jogl/classes/com/jogamp/opengl/av/GLMediaEventListener.java
new file mode 100644
index 000000000..a02c8a362
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/av/GLMediaEventListener.java
@@ -0,0 +1,17 @@
+
+package com.jogamp.opengl.av;
+
+import com.jogamp.opengl.av.GLMediaPlayer.TextureFrame;
+
+public interface GLMediaEventListener {
+
+ static final int EVENT_CHANGE_SIZE = 1<<0;
+ static final int EVENT_CHANGE_FPS = 1<<1;
+ static final int EVENT_CHANGE_BPS = 1<<2;
+ static final int EVENT_CHANGE_LENGTH = 1<<3;
+
+ public void attributesChanges(GLMediaPlayer mp, int event_mask);
+ public void newFrameAvailable(GLMediaPlayer mp, TextureFrame frame);
+
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/av/GLMediaPlayer.java b/src/jogl/classes/com/jogamp/opengl/av/GLMediaPlayer.java
new file mode 100644
index 000000000..71e0e16d9
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/av/GLMediaPlayer.java
@@ -0,0 +1,90 @@
+package com.jogamp.opengl.av;
+
+import java.io.IOException;
+import java.net.URL;
+
+import javax.media.opengl.GL;
+
+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>
+ * </ul>
+ */
+public interface GLMediaPlayer {
+
+ public static class TextureFrame {
+ public TextureFrame(Texture t) {
+ texture = t;
+ }
+
+ public final Texture getTexture() { return texture; }
+
+ public String toString() {
+ return "TextureFrame[" + texture + "]";
+ }
+ protected final Texture texture;
+ }
+
+ /** Sets the stream to be used. Initializes all stream related states and GL resources. */
+ public void setStream(GL gl, URL url) throws IOException;
+
+ /** Releases the GL and stream resources. */
+ public void destroy(GL gl);
+
+ public void setPlaySpeed(float rate);
+
+ public float getPlaySpeed();
+
+ public void start();
+
+ public void pause();
+
+ public void stop();
+
+ /**
+ * @return time current position in milliseconds
+ **/
+ public int 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 boolean isValid();
+
+ public URL getURL();
+
+ public String getVideoCodec();
+
+ public String getAudioCodec();
+
+ public long getTotalFrames();
+
+ public long getBitrate();
+
+ public int getFramerate();
+
+ public int getWidth();
+
+ public int getHeight();
+
+ public String toString();
+
+ public void addEventListener(GLMediaEventListener l);
+
+ public void removeEventListener(GLMediaEventListener l);
+
+ public GLMediaEventListener[] getEventListeners();
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/av/GLMediaPlayerFactory.java b/src/jogl/classes/com/jogamp/opengl/av/GLMediaPlayerFactory.java
new file mode 100644
index 000000000..0025a70ba
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/av/GLMediaPlayerFactory.java
@@ -0,0 +1,18 @@
+package com.jogamp.opengl.av;
+
+import com.jogamp.common.os.AndroidVersion;
+import com.jogamp.common.os.Platform;
+import com.jogamp.common.util.ReflectionUtil;
+
+public class GLMediaPlayerFactory {
+ private static final String AndroidGLMediaPlayerAPI14ClazzName = "jogamp.opengl.android.av.AndroidGLMediaPlayerAPI14";
+
+ public static GLMediaPlayer create() {
+ if(Platform.OS_TYPE.equals(Platform.OSType.ANDROID)) {
+ if(AndroidVersion.SDK_INT >= 14) {
+ return (GLMediaPlayer) ReflectionUtil.createInstance(AndroidGLMediaPlayerAPI14ClazzName, GLMediaPlayerFactory.class.getClassLoader());
+ }
+ }
+ return null;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/openmax/OMXEventListener.java b/src/jogl/classes/com/jogamp/openmax/OMXEventListener.java
deleted file mode 100644
index 08cfeccde..000000000
--- a/src/jogl/classes/com/jogamp/openmax/OMXEventListener.java
+++ /dev/null
@@ -1,14 +0,0 @@
-
-package com.jogamp.openmax;
-
-public interface OMXEventListener {
-
- static final int EVENT_CHANGE_SIZE = 1<<0;
- static final int EVENT_CHANGE_FPS = 1<<1;
- static final int EVENT_CHANGE_BPS = 1<<2;
- static final int EVENT_CHANGE_LENGTH = 1<<3;
-
- public void changedAttributes(OMXInstance omx, int event_mask);
-
-}
-
diff --git a/src/jogl/classes/com/jogamp/openmax/OMXInstance.java b/src/jogl/classes/com/jogamp/openmax/OMXInstance.java
deleted file mode 100644
index 7c373a0ef..000000000
--- a/src/jogl/classes/com/jogamp/openmax/OMXInstance.java
+++ /dev/null
@@ -1,509 +0,0 @@
-
-package com.jogamp.openmax;
-
-import javax.media.opengl.*;
-import javax.media.opengl.glu.GLU;
-import com.jogamp.opengl.util.texture.*;
-
-import jogamp.opengl.egl.EGL;
-import jogamp.opengl.egl.EGLContext;
-import jogamp.opengl.egl.EGLDrawable;
-import jogamp.opengl.egl.EGLExt;
-
-import java.net.URL;
-import java.nio.ByteBuffer;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.util.*;
-
-public class OMXInstance {
- private long moviePtr = 0;
-
- protected String path = null;
- protected URL url = null;
-
- // *** Texture impl
- protected Texture texture = null; // holds the last fetched texture
-
- protected float playSpeed = 1.0f;
-
- /**
- * The following data is set by the setStream function,
- * and may be set by the native OMX implementation,
- * in case the stream attributes changes (see attributesUpdated)
- */
- protected int width = 0;
- protected int height = 0;
- protected int fps = 0; // frames per seconds
- protected long bps = 0; // bits per seconds
- protected long totalFrames = 0; // duration in frames
- protected String acodec = null;
- protected String vcodec = null;
-
- /**
- * Old stream values, before the last attributesUpdated)
- */
- protected int o_width = 0;
- protected int o_height = 0;
- protected int o_fps = 0; // frames per seconds
- protected long o_bps = 0; // bits per seconds
- protected long o_totalFrames = 0; // duration in frames
-
- static class EGLImageTexture {
- public EGLImageTexture(com.jogamp.opengl.util.texture.Texture t, long i, long s) {
- texture = t; image = i; sync = s;
- }
- public String toString() {
- return "EGLImageTexture[" + texture + ", image " + image + ", sync "+sync+"]";
- }
- protected com.jogamp.opengl.util.texture.Texture texture;
- protected long image;
- protected long sync;
- }
- private EGLImageTexture[] eglImgTexs=null;
- private HashMap eglImgTexsMap = new HashMap();
- protected int textureNum;
-
- private EGLExt eglExt = null;
- private long eglSurface = 0;
- private long eglDisplay = 0;
- private long eglContext = 0;
- private int sWidth=0, sHeight=0;
-
- private GL initGLData(GL gl) {
- if(null==gl) {
- throw new RuntimeException("No current GL");
- }
- EGLContext eglCtx = (EGLContext) gl.getContext();
- if(null==eglCtx) {
- throw new RuntimeException("No current EGL context");
- }
- EGLDrawable eglDrawable = (EGLDrawable) eglCtx.getGLDrawable();
- if(null==eglDrawable) {
- throw new RuntimeException("No valid drawable");
- }
- eglContext = eglCtx.getHandle();
- eglDisplay = eglDrawable.getDisplay();
- eglSurface = eglDrawable.getHandle();
- eglExt = eglCtx.getEGLExt();
- if(null==eglExt) {
- throw new RuntimeException("No valid EGLExt");
- }
-
- int iTmp[] = new int[1];
- EGL.eglQuerySurface(eglDisplay, eglSurface, EGL.EGL_WIDTH, iTmp, 0);
- sWidth=iTmp[0];
- EGL.eglQuerySurface(eglDisplay, eglSurface, EGL.EGL_HEIGHT, iTmp, 0);
- sHeight=iTmp[0];
- System.out.println("surface size: "+width+"x"+height);
- System.out.println(eglDrawable);
- System.out.println(eglCtx);
- System.out.println("EGL Extensions : "+EGL.eglQueryString(eglDisplay, EGL.EGL_EXTENSIONS));
- System.out.println("EGL CLIENT APIs: "+EGL.eglQueryString(eglDisplay, EGL.EGL_CLIENT_APIS));
- return gl;
- }
-
- public OMXInstance() {
- moviePtr = _createInstance();
- if(0==moviePtr) {
- throw new GLException("Couldn't create OMXInstance");
- }
- }
- native long _createInstance();
-
- public synchronized void setStream(int textureNum, URL u) {
- if(0==moviePtr) {
- throw new GLException("OMX native instance null");
- }
- this.textureNum=textureNum;
- url = u;
- if (url == null) {
- System.out.println("setURL (null)");
- stop();
- return;
- }
- path=null;
- if (url.getProtocol() == null || "file".equals(url.getProtocol())) {
- // CV only accepts absolute paths
- try {
- File file = new File(url.getPath());
- if (!file.exists()) {
- throw new RuntimeException(new FileNotFoundException(file.toString()));
- }
- path = file.getCanonicalPath();
- System.out.println("setURL: path "+path);
- } catch (Exception e) {
- e.printStackTrace();
- throw new RuntimeException(e);
- }
- }
- path = replaceAll(path, "\\", "/").trim();
- if(null==path) {
- throw new RuntimeException("Couldn't parse stream URL: "+url);
- }
- System.out.println("setURL: clean path "+path);
-
- System.out.println("setURL: p1 "+this);
- _setStream(moviePtr, textureNum, path);
- System.out.println("setURL: p2 "+this);
- }
- native void _setStream(long moviePtr, int textureNum, String path);
-
- public synchronized void setStreamAllEGLImageTexture2D(GL gl) {
- if(0==moviePtr) {
- throw new GLException("OMX native instance null");
- }
- if(null==vcodec) {
- return;
- }
- gl = initGLData(gl);
-
- if(null!=eglImgTexs) {
- removeAllEGLImageTexture2D(gl);
- } else {
- eglImgTexs = new EGLImageTexture[textureNum];
- }
-
- int[] tmp = new int[1];
- int tex, e;
-
- errorCheckGL(gl, "i.1");
- gl.glEnable(gl.GL_TEXTURE_2D);
- errorCheckGL(gl, "i.2");
-
- for(int i=0; i<textureNum; i++) {
- String s0 = String.valueOf(i);
- gl.glGenTextures(1, tmp, 0);
- tex=tmp[0];
- if( (e=gl.glGetError()) != GL.GL_NO_ERROR || 0>tex ) {
- throw new RuntimeException("TextureName creation failed: "+e);
- }
- gl.glBindTexture(gl.GL_TEXTURE_2D, tex);
-
- // create space for buffer with a texture
- gl.glTexImage2D(
- gl.GL_TEXTURE_2D, // 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
- gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_NEAREST);
- gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST);
-
- long image=0, sync=0;
-
- // create EGLImage from texture
- tmp[0] = EGL.EGL_NONE;
- image = eglExt.eglCreateImageKHR(
- eglDisplay,
- eglContext,
- eglExt.EGL_GL_TEXTURE_2D_KHR,
- tex,
- tmp, 0);
- if (0==image) {
- throw new RuntimeException("EGLImage creation failed: "+EGL.eglGetError()+", dpy "+eglDisplay+", ctx "+eglContext+", tex "+tex);
- }
-
- // Create sync object so that we can be sure that gl has finished
- // rendering the EGLImage texture before we tell OpenMAX to fill
- // it with a new frame.
- tmp[0] = EGL.EGL_NONE;
- sync = eglExt.eglCreateSyncKHR(
- eglDisplay,
- eglExt.EGL_SYNC_FENCE_KHR, tmp, 0);
-
- _setStreamEGLImageTexture2D(moviePtr, i, tex, image, sync);
-
- eglImgTexs[i] = new EGLImageTexture(
- com.jogamp.opengl.util.texture.TextureIO.newTexture(tex,
- javax.media.opengl.GL2.GL_TEXTURE_2D,
- width,
- height,
- width,
- height,
- true),
- image, sync);
- eglImgTexsMap.put(new Integer(tex), eglImgTexs[i]);
- }
- gl.glDisable(gl.GL_TEXTURE_2D);
- }
- native void _setStreamEGLImageTexture2D(long moviePtr, int i, int tex, long image, long sync);
-
- public synchronized void activateStream() {
- if(0==moviePtr) {
- throw new GLException("OMX native instance null");
- }
- _activateStream(moviePtr);
- }
- native void _activateStream(long moviePtr);
-
- public synchronized void detachVideoRenderer() {
- if(0==moviePtr) {
- throw new GLException("OMX native instance null");
- }
- _detachVideoRenderer(moviePtr);
- }
- native void _detachVideoRenderer(long moviePtr); // stop before
-
- public synchronized void attachVideoRenderer() {
- if(0==moviePtr) {
- throw new GLException("OMX native instance null");
- }
- _attachVideoRenderer(moviePtr);
- }
- native void _attachVideoRenderer(long moviePtr); // detach before
-
- public synchronized void setPlaySpeed(float rate) {
- if(0==moviePtr) {
- throw new GLException("OMX native instance null");
- }
- _setPlaySpeed(moviePtr, rate);
- playSpeed = rate;
- }
- public synchronized float getPlaySpeed() {
- return playSpeed;
- }
- native void _setPlaySpeed(long moviePtr, float rate);
-
- /** @return time position after issuing the command */
- public synchronized float play() {
- if(0==moviePtr) {
- throw new GLException("OMX native instance null");
- }
- return _play(moviePtr);
- }
- native float _play(long moviePtr);
-
- /** @return time position after issuing the command */
- public synchronized float pause() {
- if(0==moviePtr) {
- throw new GLException("OMX native instance null");
- }
- return _pause(moviePtr);
- }
- native float _pause(long moviePtr);
-
- /** @return time position after issuing the command */
- public synchronized float stop() {
- if(0==moviePtr) {
- throw new GLException("OMX native instance null");
- }
- return _stop(moviePtr);
- }
- native float _stop(long moviePtr);
-
- /** @return time position after issuing the command */
- public synchronized float seek(float pos) {
- if(0==moviePtr) {
- throw new GLException("OMX native instance null");
- }
- return _seek(moviePtr, pos);
- }
- native float _seek(long moviePtr, float position);
-
- public synchronized Texture getLastTextureID() {
- return texture;
- }
- public synchronized Texture getNextTextureID() {
- if(0==moviePtr) {
- throw new GLException("OMX native instance null");
- }
- texture=null;
- EGLImageTexture eglImgTex = (EGLImageTexture) eglImgTexsMap.get(new Integer(_getNextTextureID(moviePtr)));
- if(null!=eglImgTex) {
- texture = eglImgTex.texture;
- }
- return texture;
- }
- native int _getNextTextureID(long moviePtr);
-
- public synchronized float getCurrentPosition() {
- if(0==moviePtr) {
- throw new GLException("OMX native instance null");
- }
- return _getCurrentPosition(moviePtr);
- }
- native float _getCurrentPosition(long moviePtr);
-
- public synchronized void destroy(GL gl) {
- removeAllEGLImageTexture2D(gl);
- if (moviePtr != 0) {
- long ptr = moviePtr;
- moviePtr = 0;
- _destroyInstance(ptr);
-
- eglExt=null;
- eglSurface=0;
- eglDisplay=0;
- eglContext=0;
- }
- }
- protected synchronized void finalize() {
- if (moviePtr != 0) {
- destroy(null);
- }
- }
- native void _destroyInstance(long moviePtr);
-
- public synchronized boolean isValid() {
- return (moviePtr != 0);
- }
- public synchronized String getPath() {
- return path;
- }
- public synchronized URL getURL() {
- return url;
- }
- public synchronized String getVideoCodec() {
- return vcodec;
- }
- public synchronized String getAudioCodec() {
- return acodec;
- }
- public synchronized long getTotalFrames() {
- return totalFrames;
- }
- public synchronized long getBitrate() {
- return bps;
- }
- public synchronized int getFramerate() {
- return fps;
- }
- public synchronized int getWidth() {
- return width;
- }
- public synchronized int getHeight() {
- return height;
- }
- public synchronized String toString() {
- return "OMXInstance [ stream [ video [ "+vcodec+", "+width+"x"+height+", "+fps+"fps, "+bps+"bsp, "+totalFrames+"f ] ] ]";
- }
-
- /**
- * Java callback method issued by the native OMX backend
- */
- private void saveAttributes() {
- o_width = width;
- o_height = height;
- o_fps = fps;
- o_bps = bps;
- o_totalFrames = totalFrames;
- }
-
- private void attributesUpdated() {
- int event_mask = 0;
- if( o_width != width || o_height != height ) {
- event_mask |= OMXEventListener.EVENT_CHANGE_SIZE;
- }
- if( o_fps != fps ) {
- event_mask |= OMXEventListener.EVENT_CHANGE_FPS;
- }
- if( o_bps != bps ) {
- event_mask |= OMXEventListener.EVENT_CHANGE_BPS;
- }
- if( o_totalFrames != totalFrames ) {
- event_mask |= OMXEventListener.EVENT_CHANGE_LENGTH;
- }
- if(0==event_mask) {
- return;
- }
-
- ArrayList listeners = null;
- synchronized(this) {
- listeners = eventListeners;
- }
- for(Iterator i = listeners.iterator(); i.hasNext(); ) {
- OMXEventListener l = (OMXEventListener) i.next();
- l.changedAttributes(this, event_mask);
- }
- }
-
- private String replaceAll(String orig, String search, String repl) {
- String dest=null;
- // In case replaceAll / java.util.regex.* is not supported (-> CVM)
- int i=0,j;
- dest = new String();
- while((j=orig.indexOf(search, i))>=0) {
- dest=dest.concat(orig.substring(i, j));
- dest=dest.concat(repl);
- i=j+1;
- }
- return dest.concat(orig.substring(i, orig.length()));
- }
-
- private void removeAllEGLImageTexture2D(GL gl) {
- if (moviePtr != 0) {
- if(null==eglExt) {
- throw new RuntimeException("No valid EGLExt");
- }
-
- texture = null;
- for(int i=0; i<textureNum; i++) {
- if(null!=eglImgTexs[i]) {
- if(0!=eglImgTexs[i].image) {
- eglExt.eglDestroyImageKHR(
- eglDisplay,
- eglImgTexs[i].image);
- }
- if(0!=eglImgTexs[i].sync) {
- eglExt.eglDestroySyncKHR(eglDisplay, eglImgTexs[i].sync);
- }
- if(null!=gl) {
- eglImgTexs[i].texture.destroy(gl);
- }
- eglImgTexs[i]=null;
- }
- }
- eglImgTexsMap.clear();
- }
- }
-
- private void errorCheckGL(GL gl, String s) {
- int e;
- if( (e=gl.glGetError()) != GL.GL_NO_ERROR ) {
- System.out.println("GL Error: ("+s+"): "+e);
- }
- }
-
- private void errorCheckEGL(String s) {
- int e;
- if( (e=EGL.eglGetError()) != EGL.EGL_SUCCESS ) {
- System.out.println("EGL Error: ("+s+"): 0x"+Integer.toHexString(e));
- }
- }
-
-
- //
- // OMXEventListener Support
- //
-
- public synchronized void addEventListener(OMXEventListener l) {
- if(l == null) {
- return;
- }
- ArrayList newEventListeners = (ArrayList) eventListeners.clone();
- newEventListeners.add(l);
- eventListeners = newEventListeners;
- }
-
- public synchronized void removeEventListener(OMXEventListener l) {
- if (l == null) {
- return;
- }
- ArrayList newEventListeners = (ArrayList) eventListeners.clone();
- newEventListeners.remove(l);
- eventListeners = newEventListeners;
- }
-
- public synchronized OMXEventListener[] getEventListeners() {
- return (OMXEventListener[]) eventListeners.toArray();
- }
-
- private ArrayList eventListeners = new ArrayList();
-
-}
-
diff --git a/src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java b/src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java
new file mode 100644
index 000000000..adfe2a048
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java
@@ -0,0 +1,195 @@
+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;
+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.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)}
+ * Android API Level 14: {@link Surface#Surface(android.graphics.SurfaceTexture)}
+ */
+public class AndroidGLMediaPlayerAPI14 extends GLMediaPlayerImpl {
+ MediaPlayer mp;
+ boolean updateSurface = false;
+
+ 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
+ public void start() {
+ mp.start();
+ }
+
+ @Override
+ public void pause() {
+ mp.pause();
+ }
+
+ @Override
+ public void stop() {
+ mp.stop();
+ }
+
+ @Override
+ public int seek(int msec) {
+ mp.seekTo(msec);
+ return mp.getCurrentPosition();
+ }
+
+ @Override
+ public Texture getNextTextureID() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public int getCurrentPosition() {
+ return mp.getCurrentPosition();
+ }
+
+ @Override
+ public boolean isValid() {
+ return true;
+ }
+
+ AndroidTextureFrame androidTextureFrame = null;
+
+ @Override
+ protected void destroyImpl(GL gl) {
+ 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);
+ }
+ mp.prepare();
+
+ 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();
+ 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);
+
+ SurfaceTexture stex = new SurfaceTexture(tex[idx]);
+ stex.setOnFrameAvailableListener(onFrameAvailableListener);
+
+ return new AndroidTextureFrame( com.jogamp.opengl.util.texture.TextureIO.newTexture(tex[idx],
+ GLES2.GL_TEXTURE_EXTERNAL_OES,
+ width, height,
+ width, height,
+ true), stex);
+ }
+
+ protected OnFrameAvailableListener onFrameAvailableListener = new OnFrameAvailableListener() {
+ @Override
+ public void onFrameAvailable(SurfaceTexture surfaceTexture) {
+ frameNumber++;
+ updateSurface = true;
+ }
+ };
+
+ @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/EGLMediaPlayerImpl.java b/src/jogl/classes/jogamp/opengl/av/EGLMediaPlayerImpl.java
new file mode 100644
index 000000000..ef3d5072c
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/av/EGLMediaPlayerImpl.java
@@ -0,0 +1,109 @@
+package jogamp.opengl.av;
+
+import javax.media.opengl.GLContext;
+
+import com.jogamp.opengl.util.texture.Texture;
+
+import jogamp.opengl.egl.EGL;
+import jogamp.opengl.egl.EGLContext;
+import jogamp.opengl.egl.EGLDrawable;
+import jogamp.opengl.egl.EGLExt;
+
+public abstract class EGLMediaPlayerImpl extends GLMediaPlayerImpl {
+ TextureType texType;
+ boolean useKHRSync;
+
+ public enum TextureType {
+ GL(0), KHRImage(1);
+
+ public final int id;
+
+ TextureType(int id){
+ this.id = id;
+ }
+ }
+
+ public static class EGLTextureFrame extends TextureFrame {
+
+ public EGLTextureFrame(Texture t, long khrImage, long khrSync) {
+ super(t);
+ this.image = khrImage;
+ this.sync = khrSync;
+ }
+
+ public final long getImage() { return image; }
+ public final long getSync() { return sync; }
+
+ public String toString() {
+ return "EGLTextureFrame[" + texture + ", img "+ image + ", sync "+ sync+"]";
+ }
+ protected final long image;
+ protected final long sync;
+ }
+
+
+ protected EGLMediaPlayerImpl() {
+ this(TextureType.GL, false);
+ }
+
+ protected EGLMediaPlayerImpl(TextureType texType, boolean useKHRSync) {
+ super();
+ this.texType = texType;
+ this.useKHRSync = useKHRSync;
+ }
+
+ @Override
+ protected TextureFrame createTexImage(GLContext ctx, int idx, int[] tex) {
+ final Texture texture = super.createTexImageImpl(ctx, idx, tex, true);
+ final long image;
+ final long sync;
+
+ final EGLContext eglCtx = (EGLContext) ctx;
+ final EGLExt eglExt = eglCtx.getEGLExt();
+ final EGLDrawable eglDrawable = (EGLDrawable) eglCtx.getGLDrawable();
+ int[] tmp = new int[1];
+
+ if(TextureType.KHRImage == texType) {
+ // create EGLImage from texture
+ tmp[0] = EGL.EGL_NONE;
+ image = eglExt.eglCreateImageKHR( eglDrawable.getDisplay(), eglCtx.getHandle(),
+ EGLExt.EGL_GL_TEXTURE_2D_KHR,
+ tex[idx], tmp, 0);
+ if (0==image) {
+ throw new RuntimeException("EGLImage creation failed: "+EGL.eglGetError()+", ctx "+eglCtx+", tex "+tex[idx]+", err "+toHexString(EGL.eglGetError()));
+ }
+ } else {
+ image = 0;
+ }
+
+ if(useKHRSync) {
+ // Create sync object so that we can be sure that gl has finished
+ // rendering the EGLImage texture before we tell OpenMAX to fill
+ // it with a new frame.
+ tmp[0] = EGL.EGL_NONE;
+ sync = eglExt.eglCreateSyncKHR(eglDrawable.getDisplay(), EGLExt.EGL_SYNC_FENCE_KHR, tmp, 0);
+ if (0==sync) {
+ throw new RuntimeException("EGLSync creation failed: "+EGL.eglGetError()+", ctx "+eglCtx+", err "+toHexString(EGL.eglGetError()));
+ }
+ } else {
+ sync = 0;
+ }
+ return new EGLTextureFrame(texture, image, sync);
+ }
+
+ @Override
+ protected void destroyTexImage(GLContext ctx, TextureFrame imgTex) {
+ final EGLContext eglCtx = (EGLContext) ctx;
+ final EGLExt eglExt = eglCtx.getEGLExt();
+ final EGLDrawable eglDrawable = (EGLDrawable) eglCtx.getGLDrawable();
+ final EGLTextureFrame eglTex = (EGLTextureFrame) imgTex;
+
+ if(0!=eglTex.getImage()) {
+ eglExt.eglDestroyImageKHR(eglDrawable.getDisplay(), eglTex.getImage());
+ }
+ if(0!=eglTex.getSync()) {
+ eglExt.eglDestroySyncKHR(eglDrawable.getDisplay(), eglTex.getSync());
+ }
+ super.destroyTexImage(ctx, imgTex);
+ }
+}
diff --git a/src/jogl/classes/jogamp/opengl/av/GLMediaPlayerImpl.java b/src/jogl/classes/jogamp/opengl/av/GLMediaPlayerImpl.java
new file mode 100644
index 000000000..826bb6953
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/av/GLMediaPlayerImpl.java
@@ -0,0 +1,307 @@
+package jogamp.opengl.av;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+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 com.jogamp.opengl.av.GLMediaPlayer;
+import com.jogamp.opengl.av.GLMediaEventListener;
+import com.jogamp.opengl.util.texture.Texture;
+
+/**
+ * After object creation an implementation may customize the behavior:
+ * <ul>
+ * <li>{@link #setTextureCount(int)}</li>
+ * <li>{@link #setTextureTarget(int)}</li>
+ * <li>{@link EGLMediaPlayerImpl#setEGLTexImageAttribs(boolean, boolean)}.</li>
+ * </ul>
+ *
+ * <p>
+ * See {@link GLMediaPlayer}.
+ * </p>
+ */
+public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
+
+ protected int textureCount;
+ protected int textureTarget;
+
+ 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. */
+ protected int width = 0;
+ /** Shall be set by the {@link #setStreamImpl()} method implementation. */
+ protected int height = 0;
+ /** Shall be set by the {@link #setStreamImpl()} method implementation. */
+ protected int fps = 0;
+ /** Shall be set by the {@link #setStreamImpl()} method implementation. */
+ protected long bps = 0;
+ /** Shall be set by the {@link #setStreamImpl()} method implementation. */
+ protected long totalFrames = 0;
+ /** Shall be set by the {@link #setStreamImpl()} method implementation. */
+ protected String acodec = null;
+ /** Shall be set by the {@link #setStreamImpl()} method implementation. */
+ protected String vcodec = null;
+
+ protected long frameNumber = 0;
+
+ private TextureFrame[] texFrames = null;
+ protected HashMap<Integer, TextureFrame> texFrameMap = new HashMap<Integer, TextureFrame>();
+ private ArrayList<GLMediaEventListener> eventListeners = new ArrayList<GLMediaEventListener>();
+
+ protected GLMediaPlayerImpl() {
+ this.textureCount=3;
+ this.textureTarget=GL.GL_TEXTURE_2D;
+ }
+
+ protected final void setTextureCount(int textureCount) {
+ this.textureCount=textureCount;
+ }
+ protected final void setTextureTarget(int textureTarget) {
+ this.textureTarget=textureTarget;
+ }
+
+ @Override
+ public final void setStream(GL gl, URL url) throws IOException {
+ this.url = url;
+ if (this.url == null) {
+ System.out.println("setURL (null)");
+ stop();
+ return;
+ }
+ setStreamImpl();
+ init(gl);
+ }
+
+ /**
+ * Implementation shall set the following set of data:
+ * @see #width
+ * @see #height
+ * @see #fps
+ * @see #bps
+ * @see #totalFrames
+ * @see #acodec
+ * @see #vcodec
+ */
+ protected abstract void setStreamImpl() throws IOException;
+
+ protected final void init(GL gl) {
+ final GLContext ctx = gl.getContext();
+ if(!ctx.isCurrent()) {
+ throw new RuntimeException("Not current: "+ctx);
+ }
+
+ 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));
+ }
+ }
+
+ 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) {
+ return new TextureFrame( createTexImageImpl(ctx, idx, tex, true) );
+ }
+
+ protected Texture createTexImageImpl(GLContext ctx, int idx, int[] tex, boolean mustFlipVertically) {
+ final GL gl = ctx.getGL();
+ if( 0 > tex[idx] ) {
+ throw new RuntimeException("TextureName "+toHexString(tex[idx])+" invalid.");
+ }
+ gl.glBindTexture(textureTarget, 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));
+ }
+ }
+
+ // 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);
+
+ return com.jogamp.opengl.util.texture.TextureIO.newTexture(tex[idx],
+ textureTarget,
+ width, height,
+ width, height,
+ mustFlipVertically);
+ }
+
+ protected void destroyTexImage(GLContext ctx, TextureFrame imgTex) {
+ imgTex.getTexture().destroy(ctx.getGL());
+ }
+
+ protected void removeAllImageTextures(GLContext ctx) {
+ texture = null;
+ for(int i=0; i<textureCount; i++) {
+ final TextureFrame imgTex = texFrames[i];
+ destroyTexImage(ctx, imgTex);
+ texFrames[i] = null;
+ }
+ texFrameMap.clear();
+ }
+
+ protected void attributesUpdated(int event_mask) {
+ synchronized(eventListenersLock) {
+ for(Iterator<GLMediaEventListener> i = eventListeners.iterator(); i.hasNext(); ) {
+ i.next().attributesChanges(this, event_mask);
+ }
+ }
+ }
+ protected void newFrameAvailable(TextureFrame frame) {
+ synchronized(eventListenersLock) {
+ for(Iterator<GLMediaEventListener> i = eventListeners.iterator(); i.hasNext(); ) {
+ i.next().newFrameAvailable(this, frame);
+ }
+ }
+ }
+
+ @Override
+ public synchronized float getPlaySpeed() {
+ return playSpeed;
+ }
+
+ @Override
+ public synchronized Texture getLastTextureID() {
+ return texture;
+ }
+
+ @Override
+ public synchronized void destroy(GL gl) {
+ destroyImpl(gl);
+ removeAllImageTextures(gl.getContext());
+ }
+ protected abstract void destroyImpl(GL gl);
+
+ @Override
+ public synchronized URL getURL() {
+ return url;
+ }
+
+ @Override
+ public synchronized String getVideoCodec() {
+ return vcodec;
+ }
+
+ @Override
+ public synchronized String getAudioCodec() {
+ return acodec;
+ }
+
+ @Override
+ public synchronized long getTotalFrames() {
+ return totalFrames;
+ }
+
+ @Override
+ public synchronized long getBitrate() {
+ return bps;
+ }
+
+ @Override
+ public synchronized int getFramerate() {
+ return fps;
+ }
+
+ @Override
+ public synchronized int getWidth() {
+ return width;
+ }
+
+ @Override
+ public synchronized int getHeight() {
+ return height;
+ }
+
+ @Override
+ public synchronized String toString() {
+ return "GLMediaPlayer [ stream [ video [ "+vcodec+", "+width+"x"+height+", "+fps+"fps, "+bps+"bsp, "+totalFrames+"f ] ] ]";
+ }
+
+ @Override
+ public void addEventListener(GLMediaEventListener l) {
+ if(l == null) {
+ return;
+ }
+ synchronized(eventListenersLock) {
+ eventListeners.add(l);
+ }
+ }
+
+ @Override
+ public void removeEventListener(GLMediaEventListener l) {
+ if (l == null) {
+ return;
+ }
+ synchronized(eventListenersLock) {
+ eventListeners.remove(l);
+ }
+ }
+
+ @Override
+ public synchronized GLMediaEventListener[] getEventListeners() {
+ synchronized(eventListenersLock) {
+ return eventListeners.toArray(new GLMediaEventListener[eventListeners.size()]);
+ }
+ }
+
+ private Object eventListenersLock = new Object();
+
+ protected static final String toHexString(long v) {
+ return "0x"+Long.toHexString(v);
+ }
+ protected static final String toHexString(int v) {
+ return "0x"+Integer.toHexString(v);
+ }
+
+} \ No newline at end of file
diff --git a/src/jogl/classes/jogamp/opengl/omx/OMXGLMediaPlayer.java b/src/jogl/classes/jogamp/opengl/omx/OMXGLMediaPlayer.java
new file mode 100644
index 000000000..8f5f9c3ab
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/omx/OMXGLMediaPlayer.java
@@ -0,0 +1,238 @@
+
+package jogamp.opengl.omx;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLException;
+
+import com.jogamp.opengl.av.GLMediaEventListener;
+import com.jogamp.opengl.util.texture.Texture;
+
+import jogamp.opengl.av.EGLMediaPlayerImpl;
+import jogamp.opengl.egl.EGL;
+
+public class OMXGLMediaPlayer extends EGLMediaPlayerImpl {
+ protected long moviePtr = 0;
+
+ /**
+ * Old stream values, before the last attributesUpdated)
+ */
+ protected int o_width = 0;
+ protected int o_height = 0;
+ protected int o_fps = 0;
+ protected long o_bps = 0;
+ protected long o_totalFrames = 0;
+
+ public OMXGLMediaPlayer() {
+ super(TextureType.KHRImage, true);
+ initOMX();
+ }
+
+ protected void initOMX() {
+ moviePtr = _createInstance();
+ if(0==moviePtr) {
+ throw new GLException("Couldn't create OMXInstance");
+ }
+ }
+
+ @Override
+ 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());
+ return eglTex;
+ }
+
+ @Override
+ protected void destroyTexImage(GLContext ctx, TextureFrame imgTex) {
+ super.destroyTexImage(ctx, imgTex);
+ }
+
+ @Override
+ protected void destroyImpl(GL gl) {
+ _detachVideoRenderer(moviePtr);
+ if (moviePtr != 0) {
+ _destroyInstance(moviePtr);
+ moviePtr = 0;
+ }
+ }
+
+ @Override
+ protected void setStreamImpl() throws IOException {
+ if(0==moviePtr) {
+ throw new GLException("OMX native instance null");
+ }
+ String path=null;
+ if (url.getProtocol() == null || "file".equals(url.getProtocol())) {
+ // CV only accepts absolute paths
+ try {
+ File file = new File(url.getPath());
+ if (!file.exists()) {
+ throw new FileNotFoundException(file.toString());
+ }
+ path = file.getCanonicalPath();
+ System.out.println("setURL: path "+path);
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new IOException(e);
+ }
+ }
+ path = replaceAll(path, "\\", "/").trim();
+ if(null==path) {
+ throw new IOException("Couldn't parse stream URL: "+url);
+ }
+ System.out.println("setURL: clean path "+path);
+
+ System.out.println("setURL: p1 "+this);
+ _setStream(moviePtr, textureCount, path);
+ System.out.println("setURL: p2 "+this);
+ }
+
+
+ @Override
+ public synchronized int getCurrentPosition() {
+ if(0==moviePtr) {
+ throw new GLException("OMX native instance null");
+ }
+ return _getCurrentPosition(moviePtr);
+ }
+
+ @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");
+ }
+ _setPlaySpeed(moviePtr, rate);
+ playSpeed = rate;
+ }
+
+ /** @return time position after issuing the command */
+ @Override
+ public synchronized void start() {
+ if(0==moviePtr) {
+ throw new GLException("OMX native instance null");
+ }
+ _play(moviePtr);
+ }
+
+ /** @return time position after issuing the command */
+ @Override
+ public synchronized void pause() {
+ if(0==moviePtr) {
+ throw new GLException("OMX native instance null");
+ }
+ _pause(moviePtr);
+ }
+
+ /** @return time position after issuing the command */
+ @Override
+ public synchronized void stop() {
+ if(0==moviePtr) {
+ throw new GLException("OMX native instance null");
+ }
+ _stop(moviePtr);
+ }
+
+ /** @return time position after issuing the command */
+ @Override
+ public synchronized int seek(int msec) {
+ if(0==moviePtr) {
+ throw new GLException("OMX native instance null");
+ }
+ return _seek(moviePtr, msec);
+ }
+
+ @Override
+ public synchronized Texture getNextTextureID() {
+ if(0==moviePtr) {
+ throw new GLException("OMX native instance null");
+ }
+ texture=null;
+ TextureFrame eglImgTex = texFrameMap.get(new Integer(_getNextTextureID(moviePtr)));
+ if(null!=eglImgTex) {
+ texture = eglImgTex.getTexture();
+ }
+ return texture;
+ }
+
+ protected void attributesUpdated() {
+ int event_mask = 0;
+ if( o_width != width || o_height != height ) {
+ event_mask |= GLMediaEventListener.EVENT_CHANGE_SIZE;
+ }
+ if( o_fps != fps ) {
+ event_mask |= GLMediaEventListener.EVENT_CHANGE_FPS;
+ }
+ if( o_bps != bps ) {
+ event_mask |= GLMediaEventListener.EVENT_CHANGE_BPS;
+ }
+ if( o_totalFrames != totalFrames ) {
+ event_mask |= GLMediaEventListener.EVENT_CHANGE_LENGTH;
+ }
+ if(0==event_mask) {
+ return;
+ }
+ super.attributesUpdated(event_mask);
+ }
+
+ /**
+ * Java callback method issued by the native OMX backend
+ */
+ private void saveAttributes() {
+ o_width = width;
+ o_height = height;
+ o_fps = fps;
+ o_bps = bps;
+ o_totalFrames = totalFrames;
+ }
+
+ private String replaceAll(String orig, String search, String repl) {
+ String dest=null;
+ // In case replaceAll / java.util.regex.* is not supported (-> CVM)
+ int i=0,j;
+ dest = new String();
+ while((j=orig.indexOf(search, i))>=0) {
+ dest=dest.concat(orig.substring(i, j));
+ dest=dest.concat(repl);
+ i=j+1;
+ }
+ return dest.concat(orig.substring(i, orig.length()));
+ }
+
+ private void errorCheckEGL(String s) {
+ int e;
+ if( (e=EGL.eglGetError()) != EGL.EGL_SUCCESS ) {
+ System.out.println("EGL Error: ("+s+"): 0x"+Integer.toHexString(e));
+ }
+ }
+
+ //
+ // OMXEventListener Support
+ //
+
+ native long _createInstance();
+ native void _destroyInstance(long moviePtr);
+
+ native void _detachVideoRenderer(long moviePtr); // stop before
+ native void _attachVideoRenderer(long moviePtr); // detach before
+ native void _setStream(long moviePtr, int textureNum, String path);
+ 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 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);
+}
+
diff --git a/src/jogl/native/openmax/com_sun_openmax_OMXInstance.c b/src/jogl/native/openmax/jogamp.opengl.omx.OMXGLMediaPlayer.c
index 5317c2abc..00c0ca562 100644
--- a/src/jogl/native/openmax/com_sun_openmax_OMXInstance.c
+++ b/src/jogl/native/openmax/jogamp.opengl.omx.OMXGLMediaPlayer.c
@@ -13,7 +13,7 @@
// http://developer.apple.com/qa/qa2001/qa1149.html
// http://developer.apple.com/qa/qa2001/qa1262.html
-#include "com_jogamp_openmax_OMXInstance.h"
+#include "jogamp_opengl_omx_OMXGLMediaPlayer.h"
#include "omx_tool.h"
#include <stdarg.h>
@@ -105,7 +105,7 @@ void OMXInstance_UpdateJavaAttributes(OMXToolBasicAV_t *pOMXAV, KDboolean issueJ
}
}
-JNIEXPORT jlong JNICALL Java_com_jogamp_openmax_OMXInstance__1createInstance
+JNIEXPORT jlong JNICALL Java_jogamp_opengl_omx_OMXGLMediaPlayer__1createInstance
(JNIEnv *env, jobject instance)
{
OMXToolBasicAV_t * pOMXAV;
@@ -132,7 +132,7 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_openmax_OMXInstance__1createInstance
return (jlong) (intptr_t) (void *)pOMXAV;
}
-JNIEXPORT void JNICALL Java_com_jogamp_openmax_OMXInstance__1setStream
+JNIEXPORT void JNICALL Java_jogamp_opengl_omx_OMXGLMediaPlayer__1setStream
(JNIEnv *env, jobject instance, jlong ptr, jint vBufferNum, jstring jpath)
{
jboolean iscopy;
@@ -150,7 +150,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_openmax_OMXInstance__1setStream
fprintf(stdout, "setStream 3 ..\n"); fflush(stdout); // JAU
}
-JNIEXPORT void JNICALL Java_com_jogamp_openmax_OMXInstance__1setStreamEGLImageTexture2D
+JNIEXPORT void JNICALL Java_jogamp_opengl_omx_OMXGLMediaPlayer__1setStreamEGLImageTexture2D
(JNIEnv *env, jobject instance, jlong ptr, jint i, jint tex, jlong image, jlong sync)
{
OMXToolBasicAV_t *pOMXAV = (OMXToolBasicAV_t *)((void *)((intptr_t)ptr));
@@ -161,7 +161,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_openmax_OMXInstance__1setStreamEGLImageTe
}
}
-JNIEXPORT void JNICALL Java_com_jogamp_openmax_OMXInstance__1activateStream
+JNIEXPORT void JNICALL Java_jogamp_opengl_omx_OMXGLMediaPlayer__1activateStream
(JNIEnv *env, jobject instance, jlong ptr)
{
OMXToolBasicAV_t *pOMXAV = (OMXToolBasicAV_t *)((void *)((intptr_t)ptr));
@@ -171,52 +171,49 @@ JNIEXPORT void JNICALL Java_com_jogamp_openmax_OMXInstance__1activateStream
}
}
-JNIEXPORT void JNICALL Java_com_jogamp_openmax_OMXInstance__1attachVideoRenderer
+JNIEXPORT void JNICALL Java_jogamp_opengl_omx_OMXGLMediaPlayer__1attachVideoRenderer
(JNIEnv *env, jobject instance, jlong ptr)
{
OMXToolBasicAV_t *pOMXAV = (OMXToolBasicAV_t *)((void *)((intptr_t)ptr));
OMXToolBasicAV_AttachVideoRenderer(pOMXAV);
}
-JNIEXPORT void JNICALL Java_com_jogamp_openmax_OMXInstance__1detachVideoRenderer
+JNIEXPORT void JNICALL Java_jogamp_opengl_omx_OMXGLMediaPlayer__1detachVideoRenderer
(JNIEnv *env, jobject instance, jlong ptr)
{
OMXToolBasicAV_t *pOMXAV = (OMXToolBasicAV_t *)((void *)((intptr_t)ptr));
OMXToolBasicAV_DetachVideoRenderer(pOMXAV);
}
-JNIEXPORT void JNICALL Java_com_jogamp_openmax_OMXInstance__1setPlaySpeed
+JNIEXPORT void JNICALL Java_jogamp_opengl_omx_OMXGLMediaPlayer__1setPlaySpeed
(JNIEnv *env, jobject instance, jlong ptr, jfloat scale)
{
OMXToolBasicAV_t *pOMXAV = (OMXToolBasicAV_t *)((void *)((intptr_t)ptr));
OMXToolBasicAV_SetPlaySpeed(pOMXAV, scale);
}
-JNIEXPORT jfloat JNICALL Java_com_jogamp_openmax_OMXInstance__1play
+JNIEXPORT void JNICALL Java_jogamp_opengl_omx_OMXGLMediaPlayer__1play
(JNIEnv *env, jobject instance, jlong ptr)
{
OMXToolBasicAV_t *pOMXAV = (OMXToolBasicAV_t *)((void *)((intptr_t)ptr));
OMXToolBasicAV_PlayStart(pOMXAV);
- return OMXToolBasicAV_GetCurrentPosition(pOMXAV);
}
-JNIEXPORT jfloat JNICALL Java_com_jogamp_openmax_OMXInstance__1pause
+JNIEXPORT void JNICALL Java_jogamp_opengl_omx_OMXGLMediaPlayer__1pause
(JNIEnv *env, jobject instance, jlong ptr)
{
OMXToolBasicAV_t *pOMXAV = (OMXToolBasicAV_t *)((void *)((intptr_t)ptr));
OMXToolBasicAV_PlayPause(pOMXAV);
- return OMXToolBasicAV_GetCurrentPosition(pOMXAV);
}
-JNIEXPORT jfloat JNICALL Java_com_jogamp_openmax_OMXInstance__1stop
+JNIEXPORT void JNICALL Java_jogamp_opengl_omx_OMXGLMediaPlayer__1stop
(JNIEnv *env, jobject instance, jlong ptr)
{
OMXToolBasicAV_t *pOMXAV = (OMXToolBasicAV_t *)((void *)((intptr_t)ptr));
OMXToolBasicAV_PlayStop(pOMXAV);
- return OMXToolBasicAV_GetCurrentPosition(pOMXAV);
}
-JNIEXPORT jfloat JNICALL Java_com_jogamp_openmax_OMXInstance__1seek
+JNIEXPORT jint JNICALL Java_jogamp_opengl_omx_OMXGLMediaPlayer__1seek
(JNIEnv *env, jobject instance, jlong ptr, jfloat pos)
{
OMXToolBasicAV_t *pOMXAV = (OMXToolBasicAV_t *)((void *)((intptr_t)ptr));
@@ -224,7 +221,7 @@ JNIEXPORT jfloat JNICALL Java_com_jogamp_openmax_OMXInstance__1seek
return OMXToolBasicAV_GetCurrentPosition(pOMXAV);
}
-JNIEXPORT jint JNICALL Java_com_jogamp_openmax_OMXInstance__1getNextTextureID
+JNIEXPORT jint JNICALL Java_jogamp_opengl_omx_OMXGLMediaPlayer__1getNextTextureID
(JNIEnv *env, jobject instance, jlong ptr)
{
jint textureID = 0xffffffff;
@@ -235,7 +232,7 @@ JNIEXPORT jint JNICALL Java_com_jogamp_openmax_OMXInstance__1getNextTextureID
return textureID;
}
-JNIEXPORT jfloat JNICALL Java_com_jogamp_openmax_OMXInstance__1getCurrentPosition
+JNIEXPORT jint JNICALL Java_jogamp_opengl_omx_OMXGLMediaPlayer__1getCurrentPosition
(JNIEnv *env, jobject instance, jlong ptr)
{
OMXToolBasicAV_t *pOMXAV = (OMXToolBasicAV_t *)((void *)((intptr_t)ptr));
@@ -243,7 +240,7 @@ JNIEXPORT jfloat JNICALL Java_com_jogamp_openmax_OMXInstance__1getCurrentPositio
}
-JNIEXPORT void JNICALL Java_com_jogamp_openmax_OMXInstance__1destroyInstance
+JNIEXPORT void JNICALL Java_jogamp_opengl_omx_OMXGLMediaPlayer__1destroyInstance
(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 57fa8ad21..1f2ce7da7 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 KDfloat32 GetClockPosition(OMXToolBasicAV_t * pOMXAV)
+static KDint 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 (KDfloat32) (stamp.nTimestamp * (1.0f/(1000.0f*1000.0f)));
+ return (int) ( stamp.nTimestamp / 1000 );
}
static KDfloat32 GetClockScale(OMXToolBasicAV_t * pOMXAV)
@@ -1474,7 +1474,7 @@ GLuint OMXToolBasicAV_GetNextTextureID(OMXToolBasicAV_t * pOMXAV) {
return texID;
}
-KDfloat32 OMXToolBasicAV_GetCurrentPosition(OMXToolBasicAV_t * pOMXAV) {
+KDint OMXToolBasicAV_GetCurrentPosition(OMXToolBasicAV_t * pOMXAV) {
KDfloat32 res = -1.0f;
if(NULL==pOMXAV) {
java_throwNewRuntimeException(0, "OMX instance null\n");
diff --git a/src/jogl/native/openmax/omx_tool.h b/src/jogl/native/openmax/omx_tool.h
index d566507c1..cb0f125ec 100644
--- a/src/jogl/native/openmax/omx_tool.h
+++ b/src/jogl/native/openmax/omx_tool.h
@@ -141,7 +141,7 @@ void OMXToolBasicAV_PlayStop(OMXToolBasicAV_t * pOMXAV);
void OMXToolBasicAV_PlaySeek(OMXToolBasicAV_t * pOMXAV, KDfloat32 time);
GLuint OMXToolBasicAV_GetNextTextureID(OMXToolBasicAV_t * pOMXAV);
-KDfloat32 OMXToolBasicAV_GetCurrentPosition(OMXToolBasicAV_t * pOMXAV);
+KDint OMXToolBasicAV_GetCurrentPosition(OMXToolBasicAV_t * pOMXAV);
void OMXToolBasicAV_DestroyInstance(OMXToolBasicAV_t * pOMXAV);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java
new file mode 100755
index 000000000..f58938399
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java
@@ -0,0 +1,373 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+
+package com.jogamp.opengl.test.junit.jogl.demos.es2.av;
+
+import java.io.IOException;
+import java.net.URL;
+import java.nio.FloatBuffer;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.GLUniformData;
+import javax.media.opengl.fixedfunc.GLMatrixFunc;
+
+import com.jogamp.newt.event.MouseEvent;
+import com.jogamp.newt.event.MouseListener;
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.av.GLMediaPlayer;
+import com.jogamp.opengl.av.GLMediaEventListener;
+import com.jogamp.opengl.av.GLMediaPlayer.TextureFrame;
+import com.jogamp.opengl.av.GLMediaPlayerFactory;
+import com.jogamp.opengl.util.GLArrayDataServer;
+import com.jogamp.opengl.util.PMVMatrix;
+import com.jogamp.opengl.util.glsl.ShaderCode;
+import com.jogamp.opengl.util.glsl.ShaderProgram;
+import com.jogamp.opengl.util.glsl.ShaderState;
+
+public class MovieSimple implements MouseListener, GLEventListener, GLMediaEventListener {
+ private GLWindow window;
+ private boolean quit = false;
+ private boolean rotate = false;
+ private float zoom = -2.5f;
+ private float ang = 0f;
+ private long startTime;
+ private long curTime;
+ private String stream;
+
+ public void changedAttributes(GLMediaPlayer omx, int event_mask) {
+ System.out.println("changed stream attr ("+event_mask+"): "+omx);
+ }
+
+ public void mouseClicked(MouseEvent e) {
+ switch(e.getClickCount()) {
+ case 2:
+ quit=true;
+ break;
+ }
+ }
+ public void mouseEntered(MouseEvent e) {
+ }
+ public void mouseExited(MouseEvent e) {
+ }
+ public void mousePressed(MouseEvent e) {
+ }
+ public void mouseReleased(MouseEvent e) {
+ rotate = false;
+ zoom = -2.5f;
+ }
+ public void mouseMoved(MouseEvent e) {
+ }
+ public void mouseDragged(MouseEvent e) {
+ rotate = true;
+ zoom = -5;
+ }
+ public void mouseWheelMoved(MouseEvent e) {
+ }
+
+ public MovieSimple(String stream) {
+ this.stream = stream ;
+ }
+
+ private void run() {
+ System.err.println("MovieSimple.run()");
+ try {
+ GLCapabilities caps = new GLCapabilities(GLProfile.getGL2ES2());
+ // For emulation library, use 16 bpp
+ caps.setRedBits(5);
+ caps.setGreenBits(6);
+ caps.setBlueBits(5);
+ caps.setDepthBits(16);
+
+ window = GLWindow.create(caps);
+
+ window.addMouseListener(this);
+ window.addGLEventListener(this);
+ // window.setEventHandlerMode(GLWindow.EVENT_HANDLER_GL_CURRENT); // default
+ // window.setEventHandlerMode(GLWindow.EVENT_HANDLER_GL_NONE); // no current ..
+
+ // Size OpenGL to Video Surface
+ window.setFullscreen(true);
+ window.setVisible(true);
+
+ startTime = System.currentTimeMillis();
+ while (!quit) {
+ window.display();
+ }
+
+ // Shut things down cooperatively
+ if(null!=movie) {
+ movie.destroy(window.getGL());
+ movie=null;
+ }
+ window.destroy();
+ System.out.println("MovieSimple shut down cleanly.");
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ }
+
+ ShaderState st;
+ PMVMatrix pmvMatrix;
+
+ private void initShader(GL2ES2 gl) {
+// Create & Compile the shader objects
+ ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, 1, MovieSimple.class,
+ "shader", "shader/bin", "moviesimple");
+ ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, 1, MovieSimple.class,
+ "shader", "shader/bin", "moviesimple");
+
+ // Create & Link the shader program
+ ShaderProgram sp = new ShaderProgram();
+ sp.add(rsVp);
+ sp.add(rsFp);
+ if(!sp.link(gl, System.err)) {
+ throw new GLException("Couldn't link program: "+sp);
+ }
+
+ // Let's manage all our states using ShaderState.
+ st = new ShaderState();
+ st.attachShaderProgram(gl, sp, false);
+ }
+
+ GLMediaPlayer movie=null;
+
+ public void init(GLAutoDrawable drawable) {
+ GL2ES2 gl = drawable.getGL().getGL2ES2();
+ System.err.println("Entering initialization");
+ System.err.println("GL_VERSION=" + gl.glGetString(GL.GL_VERSION));
+ System.err.println("GL_EXTENSIONS:");
+ System.err.println(" " + gl.glGetString(GL.GL_EXTENSIONS));
+
+ pmvMatrix = new PMVMatrix();
+
+ initShader(gl);
+
+ // Push the 1st uniform down the path
+ st.useProgram(gl, true);
+
+ pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
+ pmvMatrix.glLoadIdentity();
+ pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
+ pmvMatrix.glLoadIdentity();
+
+ if(!st.uniform(gl, new GLUniformData("mgl_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf()))) {
+ throw new GLException("Error setting PMVMatrix in shader: "+st);
+ }
+ if(!st.uniform(gl, new GLUniformData("mgl_ActiveTexture", 0))) {
+ throw new GLException("Error setting mgl_ActiveTexture in shader: "+st);
+ }
+ gl.glActiveTexture(GL.GL_TEXTURE0);
+
+ float aspect = 16.0f/9.0f;
+ float xs=1f, ys=1f; // scale object
+ float ss=1f, ts=1f; // scale tex-coord
+
+ xs = aspect; // b > h
+ ys = 1f; // b > h
+ // ss = 1f/aspect; // b > h, crop width
+ // ts = 1f; // b > h
+
+ // Allocate vertex array
+ GLArrayDataServer vertices = GLArrayDataServer.createGLSL("mgl_Vertex", 3, GL.GL_FLOAT, false, 4, GL.GL_STATIC_DRAW);
+ {
+ // Fill them up
+ FloatBuffer verticeb = (FloatBuffer)vertices.getBuffer();
+ verticeb.put(-1f*xs); verticeb.put( -1f*ys); verticeb.put( 0);
+ verticeb.put(-1f*xs); verticeb.put( 1f*ys); verticeb.put( 0);
+ verticeb.put( 1f*xs); verticeb.put( -1f*ys); verticeb.put( 0);
+ verticeb.put( 1f*xs); verticeb.put( 1f*ys); verticeb.put( 0);
+ }
+ vertices.seal(gl, true);
+
+ // Allocate texcoord array
+ GLArrayDataServer texcoord = GLArrayDataServer.createGLSL("mgl_MultiTexCoord", 2, GL.GL_FLOAT, false, 4, GL.GL_STATIC_DRAW);
+ {
+ // Fill them up
+ FloatBuffer texcoordb = (FloatBuffer)texcoord.getBuffer();
+ texcoordb.put( 0f*ss); texcoordb.put( 0f*ts);
+ texcoordb.put( 0f*ss); texcoordb.put( 1f*ts);
+ texcoordb.put( 1f*ss); texcoordb.put( 0f*ts);
+ texcoordb.put( 1f*ss); texcoordb.put( 1f*ts);
+ }
+ texcoord.seal(gl, true);
+
+ GLArrayDataServer colors = GLArrayDataServer.createGLSL("mgl_Color", 4, GL.GL_FLOAT, false, 4, GL.GL_STATIC_DRAW);
+ {
+ // Fill them up
+ FloatBuffer colorb = (FloatBuffer)colors.getBuffer();
+ colorb.put( 0); colorb.put( 0); colorb.put( 0); colorb.put( 1);
+ colorb.put( 1); colorb.put( 1); colorb.put( 1); colorb.put( 1);
+ colorb.put( 0); colorb.put( 0); colorb.put( 0); colorb.put( 1);
+ colorb.put( 1); colorb.put( 1); colorb.put( 1); colorb.put( 1);
+ }
+ colors.seal(gl, true);
+
+ // OpenGL Render Settings
+ gl.glClearColor(0.2f, 0.2f, 0.2f, 1);
+ gl.glEnable(GL2ES2.GL_DEPTH_TEST);
+
+ st.useProgram(gl, false);
+
+ // Let's show the completed shader state ..
+ System.out.println(st);
+
+ try {
+ movie = GLMediaPlayerFactory.create();
+ movie.addEventListener(this);
+ // movie.setStream(4, new URL(stream));
+ movie.setStream(gl, new URL(stream));
+ System.out.println("p0 "+movie);
+ } catch (IOException ioe) { ioe.printStackTrace(); }
+ if(null!=movie) {
+ //movie.setStreamAllEGLImageTexture2D(gl);
+ //movie.activateStream();
+ //System.out.println("p1 "+movie);
+ movie.start();
+ }
+ }
+
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+ GL2ES2 gl = drawable.getGL().getGL2ES2();
+
+ st.useProgram(gl, true);
+
+ // Set location in front of camera
+ pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
+ pmvMatrix.glLoadIdentity();
+ pmvMatrix.gluPerspective(45.0f, (float)width / (float)height, 1.0f, 100.0f);
+ //pmvMatrix.glOrthof(-4.0f, 4.0f, -4.0f, 4.0f, 1.0f, 100.0f);
+
+ pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
+ pmvMatrix.glLoadIdentity();
+ pmvMatrix.glTranslatef(0, 0, zoom);
+
+ GLUniformData ud = st.getUniform("mgl_PMVMatrix");
+ if(null!=ud) {
+ // same data object
+ st.uniform(gl, ud);
+ }
+
+ st.useProgram(gl, false);
+ }
+
+ public void dispose(GLAutoDrawable drawable) {
+ GL2ES2 gl = drawable.getGL().getGL2ES2();
+
+ movie.destroy(gl);
+ movie=null;
+ pmvMatrix.destroy();
+ pmvMatrix=null;
+ st.destroy(gl);
+ st=null;
+ quit=true;
+ }
+
+ public void display(GLAutoDrawable drawable) {
+ GL2ES2 gl = drawable.getGL().getGL2ES2();
+
+ st.useProgram(gl, true);
+
+ gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+
+ if(rotate) {
+ curTime = System.currentTimeMillis();
+ ang = ((float) (curTime - startTime) * 360.0f) / 8000.0f;
+ }
+
+ if(rotate || zoom!=0f) {
+ pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
+ pmvMatrix.glLoadIdentity();
+ pmvMatrix.glTranslatef(0, 0, zoom);
+ pmvMatrix.glRotatef(ang, 0, 0, 1);
+ // pmvMatrix.glRotatef(ang, 0, 1, 0);
+
+ GLUniformData ud = st.getUniform("mgl_PMVMatrix");
+ if(null!=ud) {
+ // same data object
+ st.uniform(gl, ud);
+ }
+
+ if(!rotate) {
+ zoom=0f;
+ }
+ }
+
+
+ com.jogamp.opengl.util.texture.Texture tex = null;
+ if(null!=movie) {
+ tex=movie.getNextTextureID();
+ if(null!=tex) {
+ tex.enable(gl);
+ tex.bind(gl);
+ }
+ }
+
+ // Draw a square
+ gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, 4);
+
+ if(null!=tex) {
+ tex.disable(gl);
+ }
+
+ st.useProgram(gl, false);
+ }
+
+ public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
+ }
+
+ public static void main(String[] args) {
+ String fname="file:///Storage Card/resources/a.mp4";
+ if(args.length>0) fname=args[0];
+ new MovieSimple(fname).run();
+ System.exit(0);
+ }
+
+ @Override
+ public void attributesChanges(GLMediaPlayer mp, int event_mask) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void newFrameAvailable(GLMediaPlayer mp, TextureFrame frame) {
+ // TODO Auto-generated method stub
+
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/moviesimple.fp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/moviesimple.fp
new file mode 100644
index 000000000..c71164105
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/moviesimple.fp
@@ -0,0 +1,21 @@
+
+#ifdef GL_ES
+ #define MEDIUMP mediump
+ #define HIGHP highp
+#else
+ #define MEDIUMP
+ #define HIGHP
+#endif
+
+uniform sampler2D mgl_ActiveTexture;
+varying HIGHP vec4 mgl_texCoord;
+varying HIGHP vec4 frontColor;
+
+void main (void)
+{
+ vec4 texColor = texture2D(mgl_ActiveTexture, mgl_texCoord.st);
+
+ // mix frontColor with texture ..
+ gl_FragColor = vec4(frontColor.rgb*texColor.rgb, frontColor.a);
+}
+
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/moviesimple.vp b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/moviesimple.vp
new file mode 100644
index 000000000..0b78eb913
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/moviesimple.vp
@@ -0,0 +1,22 @@
+
+#ifdef GL_ES
+ #define MEDIUMP mediump
+ #define HIGHP highp
+#else
+ #define MEDIUMP
+ #define HIGHP
+#endif
+
+uniform MEDIUMP mat4 mgl_PMVMatrix[2];
+attribute HIGHP vec4 mgl_Vertex;
+attribute HIGHP vec4 mgl_Color;
+attribute HIGHP vec4 mgl_MultiTexCoord;
+varying HIGHP vec4 frontColor;
+varying HIGHP vec4 mgl_texCoord;
+
+void main(void)
+{
+ frontColor=mgl_Color;
+ mgl_texCoord = mgl_MultiTexCoord;
+ gl_Position = mgl_PMVMatrix[0] * mgl_PMVMatrix[1] * mgl_Vertex;
+}