diff options
Diffstat (limited to 'src/jogl')
-rw-r--r-- | src/jogl/classes/com/jogamp/opengl/av/GLMediaEventListener.java | 17 | ||||
-rw-r--r-- | src/jogl/classes/com/jogamp/opengl/av/GLMediaPlayer.java | 90 | ||||
-rw-r--r-- | src/jogl/classes/com/jogamp/opengl/av/GLMediaPlayerFactory.java | 18 | ||||
-rw-r--r-- | src/jogl/classes/com/jogamp/openmax/OMXEventListener.java | 14 | ||||
-rw-r--r-- | src/jogl/classes/com/jogamp/openmax/OMXInstance.java | 509 | ||||
-rw-r--r-- | src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java | 195 | ||||
-rw-r--r-- | src/jogl/classes/jogamp/opengl/av/EGLMediaPlayerImpl.java | 109 | ||||
-rw-r--r-- | src/jogl/classes/jogamp/opengl/av/GLMediaPlayerImpl.java | 307 | ||||
-rw-r--r-- | src/jogl/classes/jogamp/opengl/omx/OMXGLMediaPlayer.java | 238 | ||||
-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.c | 6 | ||||
-rw-r--r-- | src/jogl/native/openmax/omx_tool.h | 2 |
12 files changed, 993 insertions, 545 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); +} + 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); |