aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes
diff options
context:
space:
mode:
Diffstat (limited to 'src/jogl/classes')
-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
9 files changed, 974 insertions, 523 deletions
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);
+}
+