diff options
-rw-r--r-- | make/build.xml | 17 | ||||
-rwxr-xr-x | make/jogl_wince6_vs9/jogl_es2/jogl_es2.vcproj | 2 | ||||
-rw-r--r-- | make/make.jogl.cdcfp.linux-x86.sh | 1 | ||||
-rwxr-xr-x | src/classes/com/sun/opengl/util/texture/Texture.java | 11 | ||||
-rw-r--r-- | src/classes/com/sun/openmax/OMXEventListener.java | 14 | ||||
-rw-r--r-- | src/classes/com/sun/openmax/OMXInstance.java | 509 | ||||
-rw-r--r-- | src/native/openmax/com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl.c | 363 | ||||
-rw-r--r-- | src/native/openmax/com_sun_openmax_OMXInstance.c | 255 | ||||
-rw-r--r-- | src/native/openmax/omx_tool.c | 554 | ||||
-rw-r--r-- | src/native/openmax/omx_tool.h | 58 |
10 files changed, 1163 insertions, 621 deletions
diff --git a/make/build.xml b/make/build.xml index f8e04c737..7eb1d45e7 100644 --- a/make/build.xml +++ b/make/build.xml @@ -162,7 +162,7 @@ value="javax/media/opengl/glsl/**, com/sun/opengl/impl/glsl/**"/> <property name="java.part.openmax" - value="com/sun/javafx/media/video/openmax/**"/> + value="com/sun/openmax/**"/> <property name="java.part.sdk" value="javax/media/opengl/sdk/**"/> @@ -201,7 +201,7 @@ value="javax/media/opengl/TraceGLES1.*, javax/media/opengl/DebugGLES1.*"/> <property name="java.part.es2" - value="javax/media/opengl/**/es2/**, com/sun/opengl/**/es2/**, ${java.part.glsl}, ${java.part.openmax}"/> + value="javax/media/opengl/**/es2/**, com/sun/opengl/**/es2/**, ${java.part.glsl}"/> <property name="java.part.es2.dbg" value="javax/media/opengl/TraceGLES2.*, javax/media/opengl/DebugGLES2.*"/> @@ -1368,7 +1368,7 @@ <!-- FIXME: the Mixer should be moved to another library --> <!--include name="${rootrel.src.c.jogl}/Mixer.cpp" if="isWindows"/--> <include name="${rootrel.src.c.openmax}/omx_tool.c" if="useOpenMAX"/> - <include name="${rootrel.src.c.openmax}/com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl.c" if="useOpenMAX"/> + <include name="${rootrel.src.c.openmax}/com_sun_openmax_OMXInstance.c" if="useOpenMAX"/> </patternset> <patternset id="c.src.files.jogl.gl2es12"> @@ -1389,7 +1389,7 @@ <!-- FIXME: the Mixer should be moved to another library --> <!--include name="${rootrel.src.c.jogl}/Mixer.cpp" if="isWindows"/--> <include name="${rootrel.src.c.openmax}/omx_tool.c" if="useOpenMAX"/> - <include name="${rootrel.src.c.openmax}/com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl.c" if="useOpenMAX"/> + <include name="${rootrel.src.c.openmax}/com_sun_openmax_OMXInstance.c" if="useOpenMAX"/> </patternset> <patternset id="c.src.files.jogl.es2"> @@ -1403,7 +1403,7 @@ <include name="${rootrel.generated.c.jogl}/es2/GLES2Impl_JNI.c"/> <include name="${rootrel.src.c.jogl}/InternalBufferUtils.c"/> <include name="${rootrel.src.c.openmax}/omx_tool.c" if="useOpenMAX"/> - <include name="${rootrel.src.c.openmax}/com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl.c" if="useOpenMAX"/> + <include name="${rootrel.src.c.openmax}/com_sun_openmax_OMXInstance.c" if="useOpenMAX"/> </patternset> <patternset id="c.src.files.jogl.es1"> @@ -1419,7 +1419,7 @@ <!--include name="${rootrel.generated.c.jogl}/GLU_JNI.c"/ EMPTY --> <!--include name="${rootrel.generated.c.jogl}/es1/GLUes1_JNI.c" EMPTY /--> <include name="${rootrel.src.c.openmax}/omx_tool.c" if="useOpenMAX"/> - <include name="${rootrel.src.c.openmax}/com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl.c" if="useOpenMAX"/> + <include name="${rootrel.src.c.openmax}/com_sun_openmax_OMXInstance.c" if="useOpenMAX"/> </patternset> <patternset id="c.src.files.cg"> @@ -1522,7 +1522,7 @@ <!-- Generate the waveout Mixer header --> <!-- FIXME: this is temporary until we move this to another workspace --> <javah destdir="../build/gensrc/native/jogl" classpath="${jogl.all.jar}" class="com.sun.javafx.audio.windows.waveout.Mixer" /> - <javah destdir="../build/gensrc/native/openmax" classpath="${jogl.all.jar}" class="com.sun.javafx.media.video.openmax.OMXMoviePlayerImpl" /> + <javah destdir="../build/gensrc/native/openmax" classpath="${jogl.all.jar}" class="com.sun.openmax.OMXInstance" /> </target> <target name="c.build.jogl.awt"> @@ -1738,7 +1738,7 @@ <jar manifest="tempversion" destfile="${jogl.util.jar}"> <fileset dir="${classes}" includes="${java.part.util}" - excludes="com/sun/opengl/**/awt/**, com/sun/opengl/**/gl2/**, ${java.part.glsl}, ${java.part.openmax}"/> + excludes="com/sun/opengl/**/awt/**, com/sun/opengl/**/gl2/**, ${java.part.glsl}"/> </jar> <jar manifest="tempversion" destfile="${jogl.util.gl2.jar}"> <fileset dir="${classes}" @@ -1754,6 +1754,7 @@ <include name="javax/media/opengl/**" /> <include name="com/sun/gluegen/runtime/**" /> <include name="com/sun/opengl/**" /> + <include name="${java.part.openmax}" /> <!-- FIXME: this is temporary until we move these classes to another workspace --> <include name="com/sun/javafx/**" /> </fileset> diff --git a/make/jogl_wince6_vs9/jogl_es2/jogl_es2.vcproj b/make/jogl_wince6_vs9/jogl_es2/jogl_es2.vcproj index 577361542..1a9ad99e2 100755 --- a/make/jogl_wince6_vs9/jogl_es2/jogl_es2.vcproj +++ b/make/jogl_wince6_vs9/jogl_es2/jogl_es2.vcproj @@ -1307,7 +1307,7 @@ > </File> <File - RelativePath="..\..\..\src\native\openmax\com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl.c" + RelativePath="..\..\..\src\native\openmax\com_sun_openmax_OMXInstance.c" > </File> </Filter> diff --git a/make/make.jogl.cdcfp.linux-x86.sh b/make/make.jogl.cdcfp.linux-x86.sh index 64598509b..56296b529 100644 --- a/make/make.jogl.cdcfp.linux-x86.sh +++ b/make/make.jogl.cdcfp.linux-x86.sh @@ -18,5 +18,4 @@ ant -v \ -DisX11=true \ -DuseKD=true \ -DuseOpenMAX=true \ - -Djava.generate.skip=true \ $* 2>&1 | tee make.jogl.cdcfp.linux-x86.log diff --git a/src/classes/com/sun/opengl/util/texture/Texture.java b/src/classes/com/sun/opengl/util/texture/Texture.java index ee1c4113d..29f22e57a 100755 --- a/src/classes/com/sun/opengl/util/texture/Texture.java +++ b/src/classes/com/sun/opengl/util/texture/Texture.java @@ -266,7 +266,16 @@ public class Texture { * OpenGL-related errors occurred */ public void dispose() throws GLException { - GLU.getCurrentGL().glDeleteTextures(1, new int[] {texID}, 0); + dispose(GLU.getCurrentGL()); + } + + /** + * Disposes the native resources used by this texture object. + * + * @throws GLException if any OpenGL-related errors occurred + */ + public void dispose(GL gl) throws GLException { + gl.glDeleteTextures(1, new int[] {texID}, 0); texID = 0; } diff --git a/src/classes/com/sun/openmax/OMXEventListener.java b/src/classes/com/sun/openmax/OMXEventListener.java new file mode 100644 index 000000000..ebbf7129f --- /dev/null +++ b/src/classes/com/sun/openmax/OMXEventListener.java @@ -0,0 +1,14 @@ + +package com.sun.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/classes/com/sun/openmax/OMXInstance.java b/src/classes/com/sun/openmax/OMXInstance.java new file mode 100644 index 000000000..abddee5a8 --- /dev/null +++ b/src/classes/com/sun/openmax/OMXInstance.java @@ -0,0 +1,509 @@ + +package com.sun.openmax; + +import javax.media.opengl.*; +import javax.media.opengl.glu.GLU; +import com.sun.opengl.util.texture.*; + +import com.sun.opengl.impl.egl.EGL; +import com.sun.opengl.impl.egl.EGLContext; +import com.sun.opengl.impl.egl.EGLDrawable; +import com.sun.opengl.impl.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.sun.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.sun.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.getContext(); + eglDisplay = eglDrawable.getDisplay(); + eglSurface = eglDrawable.getSurface(); + 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.eglCreateImage( + eglDisplay, + eglContext, + eglExt.EGL_GL_TEXTURE_2D, + 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.eglCreateFenceSync( + eglDisplay, + eglExt.EGL_SYNC_PRIOR_COMMANDS_COMPLETE, tmp, 0); + + _setStreamEGLImageTexture2D(moviePtr, i, tex, image, sync); + + eglImgTexs[i] = new EGLImageTexture( + com.sun.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 dispose(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) { + dispose(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.eglDestroyImage( + eglDisplay, + eglImgTexs[i].image); + } + if(0!=eglImgTexs[i].sync) { + eglExt.eglDestroySync(eglImgTexs[i].sync); + } + if(null!=gl) { + eglImgTexs[i].texture.dispose(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+"): "+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/native/openmax/com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl.c b/src/native/openmax/com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl.c deleted file mode 100644 index a0f29beb1..000000000 --- a/src/native/openmax/com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl.c +++ /dev/null @@ -1,363 +0,0 @@ -/* - * javafx_media_video_Movie.c - * JFXFramework - * - * Created by sun on 17/02/08. - * Copyright 2007 __MyCompanyName__. All rights reserved. - * - */ - -// http://developer.apple.com/technotes/tn2005/tn2140.html -// http://developer.apple.com/qa/qa2005/qa1443.html -// http://developer.apple.com/documentation/QuickTime/Conceptual/QT7UpdateGuide/Chapter03/chapter_3_section_1.html#//apple_ref/doc/c_ref/NewMovieFromProperties -// http://developer.apple.com/qa/qa2001/qa1149.html -// http://developer.apple.com/qa/qa2001/qa1262.html - -#include "com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl.h" -#include "omx_tool.h" -#include <stdarg.h> - -static const char * const ClazzNameRuntimeException = - "java/lang/RuntimeException"; -static jclass runtimeExceptionClz=NULL; -#ifdef _WIN32_WCE - #define STDOUT_FILE "\\Storage Card\\javafx_demos\\stdout.txt" - #define STDERR_FILE "\\Storage Card\\javafx_demos\\stderr.txt" -#endif - -static void _initStatics(JNIEnv *env) -{ - jclass c; -#ifdef _WIN32_WCE - _wfreopen(TEXT(STDOUT_FILE),L"w",stdout); - _wfreopen(TEXT(STDERR_FILE),L"w",stderr); -#endif - fprintf(stdout, "_initstatics ..\n"); fflush(stdout); // JAU - if (runtimeExceptionClz != NULL) { - return; - } - - c = (*env)->FindClass(env, ClazzNameRuntimeException); - if(NULL==c) { - fprintf(stdout, "FatalError: can't find %s\n", ClazzNameRuntimeException); - (*env)->FatalError(env, ClazzNameRuntimeException); - } - runtimeExceptionClz = (jclass)(*env)->NewGlobalRef(env, c); - if(NULL==runtimeExceptionClz) { - fprintf(stdout, "FatalError: can't use %s\n", ClazzNameRuntimeException); - (*env)->FatalError(env, ClazzNameRuntimeException); - } -} - -static JNIEnv *_env = NULL; -void java_throwNewRuntimeException(JNIEnv *env, const char* format, ...) -{ - va_list ap; - char buffer[255]; - va_start(ap, format); - if(env!=NULL) { - _env=env; - } - #ifdef _WIN32 - _vsnprintf(buffer, sizeof(buffer)-1, format, ap); - #else - vsnprintf(buffer, sizeof(buffer)-1, format, ap); - #endif - va_end(ap); - buffer[sizeof(buffer)-1]=0; - fprintf(stderr, "RuntimeException: %s\n", buffer); fflush(stderr); - if(_env!=NULL) { - (*env)->ThrowNew(_env, runtimeExceptionClz, buffer); - } -} - -JNIEXPORT jlong JNICALL Java_com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl__1createInstance - (JNIEnv *env, jobject instance, jint vBufferNum) -{ - OMXToolBasicAV_t * pOMXAV; - - _initStatics(env); - _env = env; - - pOMXAV = OMXToolBasicAV_CreateInstance(vBufferNum); - - return (jlong)((intptr_t)((void *)pOMXAV)); -} - -JNIEXPORT void JNICALL Java_com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl__1setStream - (JNIEnv *env, jobject instance, jlong ptr, jstring jpath) -{ - jboolean iscopy; - OMXToolBasicAV_t *pOMXAV = (OMXToolBasicAV_t *)((void *)((intptr_t)ptr)); - - _env = env; - - fprintf(stdout, "setStream 1 ..\n"); fflush(stdout); // JAU - if (pOMXAV != NULL) { - const char *filePath = (*env)->GetStringUTFChars(env, jpath, &iscopy); - fprintf(stdout, "setStream 2 %s..\n", filePath); fflush(stdout); // JAU - OMXToolBasicAV_SetStream(pOMXAV, filePath); - (*env)->ReleaseStringChars(env, jpath, (const jchar *)filePath); - } - fprintf(stdout, "setStream 3 ..\n"); fflush(stdout); // JAU -} - -JNIEXPORT void JNICALL Java_com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl__1updateStreamInfo - (JNIEnv *env, jobject instance, jlong ptr) -{ - OMXToolBasicAV_t *pOMXAV = (OMXToolBasicAV_t *)((void *)((intptr_t)ptr)); - - _env = env; - - if (pOMXAV != NULL) { - OMXToolBasicAV_UpdateStreamInfo(pOMXAV); - } -} - -JNIEXPORT void JNICALL Java_com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl__1setEGLImageTexture2D - (JNIEnv *env, jobject instance, jlong ptr, jint i, jint tex, jlong image, jlong sync) -{ - OMXToolBasicAV_t *pOMXAV = (OMXToolBasicAV_t *)((void *)((intptr_t)ptr)); - _env = env; - if (pOMXAV != NULL) { - OMXToolBasicAV_SetEGLImageTexture2D( pOMXAV, i, (GLuint) tex, - (EGLImageKHR)(intptr_t)image, - (EGLSyncKHR)(intptr_t)sync); - } -} - -JNIEXPORT void JNICALL Java_com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl__1activateInstance - (JNIEnv *env, jobject instance, jlong ptr) -{ - OMXToolBasicAV_t *pOMXAV = (OMXToolBasicAV_t *)((void *)((intptr_t)ptr)); - - _env = env; - - if (pOMXAV != NULL) { - OMXToolBasicAV_ActivateInstance(pOMXAV); - } -} - -/* - * Class: com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl - * Method: _play - * Signature: (ILjava/nio/ByteBuffer;JFI)V - */ -JNIEXPORT void JNICALL Java_com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl__1play - (JNIEnv *env, jobject instance, jlong ptr, jlong position, jfloat rate, jint loopCount) -{ -//fprintf(stdout, "Java_com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl__1play\n"); - OMXToolBasicAV_t *pOMXAV = (OMXToolBasicAV_t *)((void *)((intptr_t)ptr)); - _env = env; - if (pOMXAV != NULL) { - if(OMXToolBasicAV_PlayStart(pOMXAV)) { - java_throwNewRuntimeException(env, "Couldn't start play %p p:%ld r:%f l%d", - pOMXAV, position, rate, loopCount); - } - } -} - -/* - * Class: com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl - * Method: _stop - * Signature: (I)I - */ -JNIEXPORT jlong JNICALL Java_com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl__1stop - (JNIEnv *env, jobject instance, jlong ptr) -{ - jlong frame = 0; - _env = env; - return frame; -} - -/* - * Class: com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl - * Method: _setVolume - * Signature: (IF)V - */ -JNIEXPORT void JNICALL Java_com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl__1setVolume - (JNIEnv *env, jobject instance, jlong ptr, jfloat volume) -{ - _env = env; -} - -/* - * Class: com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl - * Method: _getCurrentPosition - * Signature: (I)I - */ -JNIEXPORT jlong JNICALL Java_com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl__1getCurrentPosition - (JNIEnv *env, jobject instance, jlong ptr) -{ - jlong frame = 0; - _env = env; - return frame; -} - -/* - * Class: com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl - * Method: _getCurrentPosition - * Signature: (I)I - */ -JNIEXPORT jlong JNICALL Java_com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl__1getCurrentLoaded - (JNIEnv *env, jobject instance, jlong ptr) -{ - jlong frame = 0; - _env = env; - return frame; -} - -JNIEXPORT jlong JNICALL Java_com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl__1getDuration - (JNIEnv *env, jobject instance, jlong ptr) -{ - jlong frame = 0; - _env = env; - return frame; -} -/* - * Class: com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl - * Method: _step - * Signature: (IIJ)V - */ -JNIEXPORT jlong JNICALL Java_com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl__1step - (JNIEnv *env, jobject instance, jlong ptr, jint direction, jlong position) -{ -//fprintf(stdout, "Java_com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl__1step\n"); - jlong frame = position; - _env = env; - return frame; -} - -/* - * Class: com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl - * Method: _setRate - * Signature: (IF)V - */ -JNIEXPORT void JNICALL Java_com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl__1setRate - (JNIEnv *env, jobject instance, jlong ptr, jfloat rate) -{ -//fprintf(stdout, "Java_com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl__1setRate\n"); - _env = env; -} - -/* - * Class: com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl - * Method: _setRate - * Signature: (IF)V - */ -JNIEXPORT jlong JNICALL Java_com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl__1setCurrentPosition - (JNIEnv *env, jobject obj, jlong ptr, jlong position) -{ -//fprintf(stdout, "Java_com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl__1setRate\n"); - _env = env; - return position; -} - -/* - * Class: com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl - * Method: _lock - * Signature: (I)V - */ -JNIEXPORT void JNICALL Java_com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl__1lock - (JNIEnv *env, jobject instance, jlong ptr) -{ -//fprintf(stdout, "Java_com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl__1lock\n"); - _env = env; -} - -/* - * Class: com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl - * Method: _unlock - * Signature: (I)V - */ -JNIEXPORT void JNICALL Java_com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl__1unlock - (JNIEnv *env, jobject instance, jlong ptr) -{ -//fprintf(stdout, "Java_com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl__1unlock\n"); - _env = env; -} - -/* - * Class: com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl - * Method: _getTextureID - * Signature: (I)I - */ -JNIEXPORT jint JNICALL Java_com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl__1getTextureID - (JNIEnv *env, jobject instance, jlong ptr) -{ -//fprintf(stdout, "Java_com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl__1getTextureID\n"); - jint textureID = 0xffffffff; - OMXToolBasicAV_t *pOMXAV = (OMXToolBasicAV_t *)((void *)((intptr_t)ptr)); - _env = env; - if (pOMXAV != NULL) { - textureID = OMXToolBasicAV_GetTexture(pOMXAV); - } - return textureID; -} - -/* - * Class: com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl - * Method: _getWidth - * Signature: (I)I - */ -JNIEXPORT jint JNICALL Java_com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl__1getWidth - (JNIEnv *env, jobject instance, jlong ptr) -{ -//fprintf(stdout, "Java_com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl__1getWidth\n"); - jint width = 0; - - OMXToolBasicAV_t *pOMXAV = (OMXToolBasicAV_t *)((void *)((intptr_t)ptr)); - _env = env; - if (pOMXAV != NULL) { - width = pOMXAV->width; - } - return width; -} - -/* - * Class: com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl - * Method: _getHeight - * Signature: (I)I - */ -JNIEXPORT jint JNICALL Java_com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl__1getHeight - (JNIEnv *env, jobject instance, jlong ptr) -{ -//fprintf(stdout, "Java_com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl__1getHeight\n"); - jint height = 0; - - OMXToolBasicAV_t *pOMXAV = (OMXToolBasicAV_t *)((void *)((intptr_t)ptr)); - _env = env; - if (pOMXAV != NULL) { - height = pOMXAV->height; - } - return height; -} - -/* - * Class: com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl - * Method: _task - * Signature: (I)V - */ -JNIEXPORT void JNICALL Java_com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl__1task - (JNIEnv *env, jobject instance, jlong ptr) -{ - _env = env; -} - -/* - * Class: com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl - * Method: _destroy - * Signature: (I)V - */ -JNIEXPORT void JNICALL Java_com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl__1destroyInstance - (JNIEnv *env, jobject instance, jlong ptr) -{ -//fprintf(stdout, "Java_com_sun_javafx_media_video_openmax_OMXMoviePlayerImpl__1destroy\n"); - OMXToolBasicAV_t *pOMXAV = (OMXToolBasicAV_t *)((void *)((intptr_t)ptr)); - _env = env; - if (pOMXAV != NULL) { - OMXToolBasicAV_DestroyInstance(pOMXAV); - } -} - - diff --git a/src/native/openmax/com_sun_openmax_OMXInstance.c b/src/native/openmax/com_sun_openmax_OMXInstance.c new file mode 100644 index 000000000..c763b0dd6 --- /dev/null +++ b/src/native/openmax/com_sun_openmax_OMXInstance.c @@ -0,0 +1,255 @@ +/* + * javafx_media_video_Movie.c + * JFXFramework + * + * Created by sun on 17/02/08. + * Copyright 2007 __MyCompanyName__. All rights reserved. + * + */ + +// http://developer.apple.com/technotes/tn2005/tn2140.html +// http://developer.apple.com/qa/qa2005/qa1443.html +// http://developer.apple.com/documentation/QuickTime/Conceptual/QT7UpdateGuide/Chapter03/chapter_3_section_1.html#//apple_ref/doc/c_ref/NewMovieFromProperties +// http://developer.apple.com/qa/qa2001/qa1149.html +// http://developer.apple.com/qa/qa2001/qa1262.html + +#include "com_sun_openmax_OMXInstance.h" +#include "omx_tool.h" +#include <stdarg.h> + +static const char * const ClazzNameRuntimeException = + "java/lang/RuntimeException"; +static jclass runtimeExceptionClz=NULL; +#ifdef _WIN32_WCE + #define STDOUT_FILE "\\Storage Card\\javafx_demos\\stdout.txt" + #define STDERR_FILE "\\Storage Card\\javafx_demos\\stderr.txt" +#endif + +static void _initStatics(JNIEnv *env) +{ + jclass c; +#ifdef _WIN32_WCE + _wfreopen(TEXT(STDOUT_FILE),L"w",stdout); + _wfreopen(TEXT(STDERR_FILE),L"w",stderr); +#endif + fprintf(stdout, "_initstatics ..\n"); fflush(stdout); // JAU + if (runtimeExceptionClz != NULL) { + return; + } + + c = (*env)->FindClass(env, ClazzNameRuntimeException); + if(NULL==c) { + fprintf(stdout, "FatalError: can't find %s\n", ClazzNameRuntimeException); + (*env)->FatalError(env, ClazzNameRuntimeException); + } + runtimeExceptionClz = (jclass)(*env)->NewGlobalRef(env, c); + if(NULL==runtimeExceptionClz) { + fprintf(stdout, "FatalError: can't use %s\n", ClazzNameRuntimeException); + (*env)->FatalError(env, ClazzNameRuntimeException); + } +} + +void java_throwNewRuntimeException(intptr_t jni_env, const char* format, ...) +{ + va_list ap; + char buffer[255]; + va_start(ap, format); + #ifdef _WIN32 + _vsnprintf(buffer, sizeof(buffer)-1, format, ap); + #else + vsnprintf(buffer, sizeof(buffer)-1, format, ap); + #endif + va_end(ap); + buffer[sizeof(buffer)-1]=0; + fprintf(stderr, "RuntimeException: %s\n", buffer); fflush(stderr); + if(jni_env!=0) { + (*((JNIEnv *)jni_env))->ThrowNew((JNIEnv *)jni_env, runtimeExceptionClz, buffer); + } +} + +void OMXInstance_SaveJavaAttributes(OMXToolBasicAV_t *pOMXAV, KDboolean issueJavaCallback) +{ + if(NULL==pOMXAV || 0==pOMXAV->jni_env || 0==pOMXAV->jni_instance) { + fprintf(stderr, "OMXInstance_SaveJavaAttributes failed"); + return; + } else if(issueJavaCallback==KD_TRUE) { + JNIEnv * env = (JNIEnv *)pOMXAV->jni_env; + jobject instance = (jobject)pOMXAV->jni_instance; + (*env)->CallVoidMethod(env, instance, (jmethodID)pOMXAV->jni_mid_saveAttributes); + } +} + +void OMXInstance_UpdateJavaAttributes(OMXToolBasicAV_t *pOMXAV, KDboolean issueJavaCallback) +{ + if(NULL==pOMXAV || 0==pOMXAV->jni_env || 0==pOMXAV->jni_instance) { + fprintf(stderr, "OMXInstance_UpdateJavaAttributes failed"); + return; + } else { + JNIEnv * env = (JNIEnv *)pOMXAV->jni_env; + jobject instance = (jobject)pOMXAV->jni_instance; + (*env)->SetIntField(env, instance, (jfieldID)pOMXAV->jni_fid_width, (jint)pOMXAV->width); + (*env)->SetIntField(env, instance, (jfieldID)pOMXAV->jni_fid_height, (jint)pOMXAV->height); + (*env)->SetIntField(env, instance, (jfieldID)pOMXAV->jni_fid_fps, (jint)pOMXAV->framerate); + (*env)->SetLongField(env, instance, (jfieldID)pOMXAV->jni_fid_bps, (jlong)pOMXAV->bitrate); + (*env)->SetLongField(env, instance, (jfieldID)pOMXAV->jni_fid_totalFrames, (jlong)(pOMXAV->length*pOMXAV->framerate)); + if(issueJavaCallback==KD_TRUE) { + (*env)->CallVoidMethod(env, instance, (jmethodID)pOMXAV->jni_mid_attributesUpdated); + } else { + if(strlen(pOMXAV->videoCodec)>0) { + (*env)->SetObjectField(env, instance, (jfieldID)pOMXAV->jni_fid_vcodec, (*env)->NewStringUTF(env, pOMXAV->videoCodec)); + } + if(strlen(pOMXAV->audioCodec)>0) { + (*env)->SetObjectField(env, instance, (jfieldID)pOMXAV->jni_fid_acodec, (*env)->NewStringUTF(env, pOMXAV->audioCodec)); + } + } + } +} + +JNIEXPORT jlong JNICALL Java_com_sun_openmax_OMXInstance__1createInstance + (JNIEnv *env, jobject instance) +{ + OMXToolBasicAV_t * pOMXAV; + + _initStatics(env); + + pOMXAV->jni_env=(intptr_t)env; + pOMXAV->jni_instance=(intptr_t)instance; + + pOMXAV = OMXToolBasicAV_CreateInstance((intptr_t)env, (intptr_t)instance); + if(NULL!=pOMXAV) { + jclass cls = (*env)->GetObjectClass(env, instance); + pOMXAV->jni_mid_saveAttributes = (intptr_t) (*env)->GetMethodID(env, cls, "saveAttributes", "()V"); + pOMXAV->jni_mid_attributesUpdated = (intptr_t) (*env)->GetMethodID(env, cls, "attributesUpdated", "()V"); + pOMXAV->jni_fid_width = (intptr_t) (*env)->GetFieldID(env, cls, "width", "I"); + pOMXAV->jni_fid_height = (intptr_t) (*env)->GetFieldID(env, cls, "height", "I"); + pOMXAV->jni_fid_fps = (intptr_t) (*env)->GetFieldID(env, cls, "fps", "I"); + pOMXAV->jni_fid_bps = (intptr_t) (*env)->GetFieldID(env, cls, "bps", "J"); + pOMXAV->jni_fid_totalFrames = (intptr_t) (*env)->GetFieldID(env, cls, "totalFrames", "J"); + pOMXAV->jni_fid_acodec = (intptr_t) (*env)->GetFieldID(env, cls, "acodec", "Ljava/lang/String;"); + pOMXAV->jni_fid_vcodec = (intptr_t) (*env)->GetFieldID(env, cls, "vcodec", "Ljava/lang/String;"); + } + + return (jlong) (intptr_t) (void *)pOMXAV; +} + +JNIEXPORT void JNICALL Java_com_sun_openmax_OMXInstance__1setStream + (JNIEnv *env, jobject instance, jlong ptr, jint vBufferNum, jstring jpath) +{ + jboolean iscopy; + OMXToolBasicAV_t *pOMXAV = (OMXToolBasicAV_t *)((void *)((intptr_t)ptr)); + + fprintf(stdout, "setStream 1 ..\n"); fflush(stdout); // JAU + if (pOMXAV != NULL) { + const char *filePath = (*env)->GetStringUTFChars(env, jpath, &iscopy); + fprintf(stdout, "setStream 2 %s..\n", filePath); fflush(stdout); // JAU + pOMXAV->jni_env=(intptr_t)env; + pOMXAV->jni_instance=(intptr_t)instance; + OMXToolBasicAV_SetStream(pOMXAV, vBufferNum, filePath); + (*env)->ReleaseStringChars(env, jpath, (const jchar *)filePath); + } + fprintf(stdout, "setStream 3 ..\n"); fflush(stdout); // JAU +} + +JNIEXPORT void JNICALL Java_com_sun_openmax_OMXInstance__1setStreamEGLImageTexture2D + (JNIEnv *env, jobject instance, jlong ptr, jint i, jint tex, jlong image, jlong sync) +{ + OMXToolBasicAV_t *pOMXAV = (OMXToolBasicAV_t *)((void *)((intptr_t)ptr)); + if (pOMXAV != NULL) { + OMXToolBasicAV_SetStreamEGLImageTexture2D( pOMXAV, i, (GLuint) tex, + (EGLImageKHR)(intptr_t)image, + (EGLSyncKHR)(intptr_t)sync); + } +} + +JNIEXPORT void JNICALL Java_com_sun_openmax_OMXInstance__1activateStream + (JNIEnv *env, jobject instance, jlong ptr) +{ + OMXToolBasicAV_t *pOMXAV = (OMXToolBasicAV_t *)((void *)((intptr_t)ptr)); + + if (pOMXAV != NULL) { + OMXToolBasicAV_ActivateStream(pOMXAV); + } +} + +JNIEXPORT void JNICALL Java_com_sun_openmax_OMXInstance__1attachVideoRenderer + (JNIEnv *env, jobject instance, jlong ptr) +{ + OMXToolBasicAV_t *pOMXAV = (OMXToolBasicAV_t *)((void *)((intptr_t)ptr)); + OMXToolBasicAV_AttachVideoRenderer(pOMXAV); +} + +JNIEXPORT void JNICALL Java_com_sun_openmax_OMXInstance__1detachVideoRenderer + (JNIEnv *env, jobject instance, jlong ptr) +{ + OMXToolBasicAV_t *pOMXAV = (OMXToolBasicAV_t *)((void *)((intptr_t)ptr)); + OMXToolBasicAV_DetachVideoRenderer(pOMXAV); +} + +JNIEXPORT void JNICALL Java_com_sun_openmax_OMXInstance__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_sun_openmax_OMXInstance__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_sun_openmax_OMXInstance__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_sun_openmax_OMXInstance__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_sun_openmax_OMXInstance__1seek + (JNIEnv *env, jobject instance, jlong ptr, jfloat pos) +{ + OMXToolBasicAV_t *pOMXAV = (OMXToolBasicAV_t *)((void *)((intptr_t)ptr)); + OMXToolBasicAV_PlaySeek(pOMXAV, pos); + return OMXToolBasicAV_GetCurrentPosition(pOMXAV); +} + +JNIEXPORT jint JNICALL Java_com_sun_openmax_OMXInstance__1getNextTextureID + (JNIEnv *env, jobject instance, jlong ptr) +{ + jint textureID = 0xffffffff; + OMXToolBasicAV_t *pOMXAV = (OMXToolBasicAV_t *)((void *)((intptr_t)ptr)); + if (pOMXAV != NULL) { + textureID = OMXToolBasicAV_GetNextTextureID(pOMXAV); + } + return textureID; +} + +JNIEXPORT jfloat JNICALL Java_com_sun_openmax_OMXInstance__1getCurrentPosition + (JNIEnv *env, jobject instance, jlong ptr) +{ + OMXToolBasicAV_t *pOMXAV = (OMXToolBasicAV_t *)((void *)((intptr_t)ptr)); + return OMXToolBasicAV_GetCurrentPosition(pOMXAV); +} + + +JNIEXPORT void JNICALL Java_com_sun_openmax_OMXInstance__1destroyInstance + (JNIEnv *env, jobject instance, jlong ptr) +{ + OMXToolBasicAV_t *pOMXAV = (OMXToolBasicAV_t *)((void *)((intptr_t)ptr)); + if (pOMXAV != NULL) { + OMXToolBasicAV_DestroyInstance(pOMXAV); + } +} + + diff --git a/src/native/openmax/omx_tool.c b/src/native/openmax/omx_tool.c index 927374f53..e9633af1b 100644 --- a/src/native/openmax/omx_tool.c +++ b/src/native/openmax/omx_tool.c @@ -24,20 +24,20 @@ #endif #include <NVOMX_IndexExtensions.h> -#if !defined(SELF_TEST) - #include <jni.h> -#endif #define NOTSET_U8 ((OMX_U8)0xDE) #define NOTSET_U16 ((OMX_U16)0xDEDE) #define NOTSET_U32 ((OMX_U32)0xDEDEDEDE) #define INIT_PARAM(_X_) (memset(&(_X_), NOTSET_U8, sizeof(_X_)), ((_X_).nSize = sizeof (_X_)), (_X_).nVersion = vOMX) +void OMXInstance_SaveJavaAttributes(OMXToolBasicAV_t *pOMXAV, KDboolean issueJavaCallback); +void OMXInstance_UpdateJavaAttributes(OMXToolBasicAV_t *pOMXAV, KDboolean issueJavaCallback); + #if !defined(SELF_TEST) -void java_throwNewRuntimeException(JNIEnv *env, const char* format, ...); +void java_throwNewRuntimeException(intptr_t jni_env, const char* format, ...); #else #include <stdarg.h> -void java_throwNewRuntimeException(void *env, const char* format, ...) { +void java_throwNewRuntimeException(intptr_t jni_env, const char* format, ...) { va_list ap; char buffer[255]; va_start(ap, format); @@ -54,11 +54,23 @@ void java_throwNewRuntimeException(void *env, const char* format, ...) { #endif static void DestroyInstanceUnlock(OMXToolBasicAV_t * pOMXAV); +#define OMXSAFEVOID(x) \ +do { \ + OMX_ERRORTYPE err = (x); \ + if (err != OMX_ErrorNone) { \ + java_throwNewRuntimeException((NULL!=pOMXAV)?pOMXAV->jni_env:0, "FAILED at %s:%d, Error: 0x%x\n", __FILE__, __LINE__, err); \ + if(NULL!=pOMXAV) { \ + DestroyInstanceUnlock(pOMXAV); \ + } \ + return; \ + } \ +} while (0); + #define OMXSAFE(x) \ do { \ OMX_ERRORTYPE err = (x); \ if (err != OMX_ErrorNone) { \ - java_throwNewRuntimeException(NULL, "FAILED at %s:%d, Error: 0x%x\n", __FILE__, __LINE__, err); \ + java_throwNewRuntimeException((NULL!=pOMXAV)?pOMXAV->jni_env:0, "FAILED at %s:%d, Error: 0x%x\n", __FILE__, __LINE__, err); \ if(NULL!=pOMXAV) { \ DestroyInstanceUnlock(pOMXAV); \ } \ @@ -70,7 +82,7 @@ do { \ do { \ OMX_ERRORTYPE err = (x); \ if (err != OMX_ErrorNone) { \ - java_throwNewRuntimeException(NULL, "FAILED at %s:%d, Error: 0x%x\n", __FILE__, __LINE__, err); \ + java_throwNewRuntimeException((NULL!=pOMXAV)?pOMXAV->jni_env:0, "FAILED at %s:%d, Error: 0x%x\n", __FILE__, __LINE__, err); \ if(NULL!=pOMXAV) { \ DestroyInstanceUnlock(pOMXAV); \ } \ @@ -149,6 +161,8 @@ static void GetComponentName(OMX_HANDLETYPE hComponent, KDchar *pName, int nameM OMX_GetComponentVersion(hComponent, pName, &v1, &v2, &uuid); } +static OMX_ERRORTYPE UpdateStreamInfo(OMXToolBasicAV_t * pOMXAV, KDboolean issueCallback); + static OMX_ERRORTYPE EventHandler( OMX_IN OMX_HANDLETYPE hComponent, OMX_IN OMX_PTR pAppData, @@ -212,6 +226,11 @@ static OMX_ERRORTYPE EventHandler( } } break; + case OMX_EventPortSettingsChanged: + { + (void) UpdateStreamInfo(pOMXAV, (pOMXAV->status>OMXAV_INIT)?KD_TRUE:KD_FALSE); + } + break; default: break; } @@ -451,7 +470,7 @@ static void DestroyInstanceUnlock(OMXToolBasicAV_t * pOMXAV) DBG_PRINT( "Destroy p2\n"); if(0!=(res1=OMXToolBasicAV_RequestState(pOMXAV, OMX_StateIdle, KD_TRUE))) { - java_throwNewRuntimeException(NULL, "Destroy - Wait for Idle Failed (%d)", res1); + java_throwNewRuntimeException(pOMXAV->jni_env, "Destroy - Wait for Idle Failed (%d)", res1); } DBG_PRINT( "Destroy p3\n"); @@ -464,7 +483,7 @@ static void DestroyInstanceUnlock(OMXToolBasicAV_t * pOMXAV) if(0!=(res2=OMXToolBasicAV_RequestState(pOMXAV, OMX_StateLoaded, KD_TRUE))) { if(!res1) { - java_throwNewRuntimeException(NULL, "Destroy - Wait for Loaded Failed (%d)", res2); + java_throwNewRuntimeException(pOMXAV->jni_env, "Destroy - Wait for Loaded Failed (%d)", res2); } } @@ -516,10 +535,9 @@ static OMX_ERRORTYPE AddFile(OMXToolBasicAV_t * pOMXAV, const KDchar* filename) return OMX_ErrorNone; } -static OMX_ERRORTYPE ProbePort(OMXToolBasicAV_t * pOMXAV, int port, KDchar* component) +static OMX_ERRORTYPE ProbePort(OMXToolBasicAV_t * pOMXAV, int port, KDchar *codec, KDchar* component) { // FIXME: Non NV case .. - KDchar codec[256]; OMX_U32 roles = 1; OMX_ERRORTYPE err = OMX_ErrorNone; OMX_INDEXTYPE eParam; @@ -536,12 +554,10 @@ static OMX_ERRORTYPE ProbePort(OMXToolBasicAV_t * pOMXAV, int port, KDchar* comp oStreamType.nPort = port; OMXSAFEERR(OMX_GetParameter(pOMXAV->comp[OMXAV_H_READER], eParam, &oStreamType)); - if (oPortDef.eDomain == OMX_PortDomainVideo) - kdStrcpy_s(codec, 128, "video_decoder."); - else if (oPortDef.eDomain == OMX_PortDomainAudio) - kdStrcpy_s(codec, 128, "audio_decoder."); - else + if (oPortDef.eDomain != OMX_PortDomainVideo && + oPortDef.eDomain != OMX_PortDomainAudio) { return OMX_ErrorNotImplemented; + } switch (oStreamType.eStreamType) { @@ -566,44 +582,25 @@ static OMX_ERRORTYPE ProbePort(OMXToolBasicAV_t * pOMXAV, int port, KDchar* comp } { + KDchar ocodec[256]; OMX_U8 *tmp = (OMX_U8*) kdMalloc(OMX_MAX_STRINGNAME_SIZE + 1); kdMemset(tmp, 0, sizeof(OMX_U8) * (OMX_MAX_STRINGNAME_SIZE + 1)); + if (oPortDef.eDomain == OMX_PortDomainVideo) + kdStrcpy_s(ocodec, 128, "video_decoder."); + else if (oPortDef.eDomain == OMX_PortDomainAudio) + kdStrcpy_s(ocodec, 128, "audio_decoder."); + kdStrncat_s(ocodec, 128, codec, kdStrlen(codec)); + err = OMX_GetComponentsOfRole(codec, &roles, &tmp); kdStrcpy_s(component, 256, (KDchar*) tmp); kdFree(tmp); + printf("%s(%s) -> %s\n", ocodec, codec, component); } - printf("%s -> %s\n", codec, component); return err != OMX_ErrorNone ? err : roles ? OMX_ErrorNone : OMX_ErrorComponentNotFound; } -static OMX_ERRORTYPE UpdateStreamInfo(OMXToolBasicAV_t * pOMXAV) -{ - OMX_PARAM_PORTDEFINITIONTYPE oPortDef; - kdMemset(&oPortDef, 0, sizeof(oPortDef)); - oPortDef.nSize = sizeof(oPortDef); - oPortDef.nVersion.s.nVersionMajor = 1; - oPortDef.nVersion.s.nVersionMinor = 1; - oPortDef.nPortIndex = 0; - OMXSAFEERR(OMX_GetParameter(pOMXAV->comp[OMXAV_H_READER], OMX_IndexParamPortDefinition, &oPortDef)); - - if (oPortDef.eDomain != OMX_PortDomainVideo) - { - kdMemset(&oPortDef, 0, sizeof(oPortDef)); - oPortDef.nSize = sizeof(oPortDef); - oPortDef.nVersion.s.nVersionMajor = 1; - oPortDef.nVersion.s.nVersionMinor = 1; - - oPortDef.nPortIndex = 1; - OMXSAFEERR(OMX_GetParameter(pOMXAV->comp[OMXAV_H_READER], OMX_IndexParamPortDefinition, &oPortDef)); - } - pOMXAV->width = oPortDef.format.video.nFrameWidth; - pOMXAV->height = oPortDef.format.video.nFrameHeight; - - return OMX_ErrorNone; -} - static int StartClock(OMXToolBasicAV_t * pOMXAV, KDboolean start, KDfloat32 time) { OMX_TIME_CONFIG_CLOCKSTATETYPE oClockState; OMX_ERRORTYPE eError = OMX_ErrorNone; @@ -626,6 +623,25 @@ static int StartClock(OMXToolBasicAV_t * pOMXAV, KDboolean start, KDfloat32 time return (OMX_ErrorNotReady == eError)?-1:0; } +static KDfloat32 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))); +} + +static KDfloat32 GetClockScale(OMXToolBasicAV_t * pOMXAV) +{ + OMX_TIME_CONFIG_SCALETYPE pScale; + INIT_PARAM(pScale); + + OMX_GetConfig(pOMXAV->comp[OMXAV_H_CLOCK], OMX_IndexConfigTimeScale, &pScale); + return (pScale.xScale / 65536.0f); +} + static KDint SetClockScale(OMXToolBasicAV_t * pOMXAV, KDfloat32 scale) { OMX_TIME_CONFIG_SCALETYPE pScale; @@ -636,6 +652,88 @@ static KDint SetClockScale(OMXToolBasicAV_t * pOMXAV, KDfloat32 scale) return 0; } +static int SetMediaPosition(OMXToolBasicAV_t * pOMXAV, KDfloat32 time) { + OMX_ERRORTYPE eError = OMX_ErrorNone; + OMX_TIME_CONFIG_TIMESTAMPTYPE timestamp; + int loop=STATE_TIMEOUT_LOOP; + INIT_PARAM(timestamp); + timestamp.nPortIndex = 0; + timestamp.nTimestamp = (OMX_TICKS) (time * 1000.0 * 1000.0); + + eError = OMX_SetConfig(pOMXAV->comp[OMXAV_H_READER], OMX_IndexConfigTimePosition, ×tamp); + while (loop>0 && OMX_ErrorNotReady == eError) + { + usleep(STATE_SLEEP*1000); + loop--; + eError = OMX_SetConfig(pOMXAV->comp[OMXAV_H_READER], OMX_IndexConfigTimePosition, ×tamp); + } + return (OMX_ErrorNotReady == eError)?-1:0; +} + +static KDfloat32 GetMediaLength(OMXToolBasicAV_t * pOMXAV) +{ + NVX_PARAM_DURATION oDuration; + OMX_INDEXTYPE eParam; + + if (OMX_ErrorNone != OMX_GetExtensionIndex(pOMXAV->comp[OMXAV_H_READER], NVX_INDEX_PARAM_DURATION, &eParam)) + return -1.0f; + + if (OMX_ErrorNone != OMX_GetParameter(pOMXAV->comp[OMXAV_H_READER], eParam, &oDuration)) + return -1.0f; + + return (KDfloat32) (oDuration.nDuration * (1.0f/(1000.0f*1000.0f))); +} + +static OMX_ERRORTYPE UpdateStreamInfo(OMXToolBasicAV_t * pOMXAV, KDboolean issueCallback) +{ + OMX_ERRORTYPE err = OMX_ErrorNone; + OMX_PARAM_PORTDEFINITIONTYPE oPortDef; + + DBG_PRINT( "Update StreamInfo p0\n" ); + + kdMemset(&oPortDef, 0, sizeof(oPortDef)); + oPortDef.nSize = sizeof(oPortDef); + oPortDef.nVersion.s.nVersionMajor = 1; + oPortDef.nVersion.s.nVersionMinor = 1; + oPortDef.nPortIndex = 0; + err = OMX_GetParameter(pOMXAV->comp[OMXAV_H_READER], OMX_IndexParamPortDefinition, &oPortDef); + if(OMX_ErrorNone!=err) { + fprintf(stderr, "UpdateStreamInfo failed - p1 0x%X", err); + return err; + } + + if (oPortDef.eDomain != OMX_PortDomainVideo) + { + kdMemset(&oPortDef, 0, sizeof(oPortDef)); + oPortDef.nSize = sizeof(oPortDef); + oPortDef.nVersion.s.nVersionMajor = 1; + oPortDef.nVersion.s.nVersionMinor = 1; + oPortDef.nPortIndex = 1; + err = OMX_GetParameter(pOMXAV->comp[OMXAV_H_READER], OMX_IndexParamPortDefinition, &oPortDef); + if(OMX_ErrorNone!=err) { + fprintf(stderr, "UpdateStreamInfo failed - p2 0x%X", err); + return err; + } + } + + DBG_PRINT( "Update StreamInfo p1\n" ); + OMXInstance_SaveJavaAttributes(pOMXAV, issueCallback); + + pOMXAV->width = oPortDef.format.video.nFrameWidth; + pOMXAV->height = oPortDef.format.video.nFrameHeight; + /* pOMXAV->stride = oPortDef.format.video.nStride; + pOMXAV->sliceHeight = oPortDef.format.video.nSliceHeight; */ + pOMXAV->framerate = oPortDef.format.video.xFramerate; + pOMXAV->bitrate = oPortDef.format.video.nBitrate; + DBG_PRINT( "Update StreamInfo p2 %dx%d, fps %d, bps %d\n", pOMXAV->width, pOMXAV->height, pOMXAV->framerate, pOMXAV->bitrate ); + pOMXAV->length = GetMediaLength(pOMXAV); + pOMXAV->speed = GetClockScale(pOMXAV); + + OMXInstance_UpdateJavaAttributes(pOMXAV, issueCallback); + + return err; +} + static int AttachAudioRenderer(OMXToolBasicAV_t * pOMXAV) { int res=0; @@ -646,7 +744,7 @@ static int AttachAudioRenderer(OMXToolBasicAV_t * pOMXAV) // FIXME: proper audio buffering .. OMXSAFE(OMX_GetHandle(&pOMXAV->comp[OMXAV_H_ABUFFERING], "OMX.Nvidia.audio.visualization", pOMXAV, &pOMXAV->callbacks)); if(0!=(res=SyncOnState(pOMXAV->comp[OMXAV_H_ABUFFERING], OMX_StateLoaded))) { - java_throwNewRuntimeException(NULL, "Loading AudioBuffering Failed (%d)", res); + java_throwNewRuntimeException(pOMXAV->jni_env, "Loading AudioBuffering Failed (%d)", res); return res; } /** @@ -668,7 +766,7 @@ static int AttachAudioRenderer(OMXToolBasicAV_t * pOMXAV) // mandatory before SetupTunnel if(0!=(res=SyncOnState(pOMXAV->comp[OMXAV_H_ARENDERER], OMX_StateLoaded))) { - java_throwNewRuntimeException(NULL, "Loading AudioRenderer Failed (%d)", res); + java_throwNewRuntimeException(pOMXAV->jni_env, "Loading AudioRenderer Failed (%d)", res); return res; } @@ -716,7 +814,7 @@ static int AttachVideoRenderer(OMXToolBasicAV_t * pOMXAV) { int i, res=0; if(KD_NULL!=pOMXAV->comp[OMXAV_H_VSCHEDULER]) { - java_throwNewRuntimeException(NULL, "Detach Video first"); + java_throwNewRuntimeException(pOMXAV->jni_env, "Detach Video first"); return -1; } OMXSAFE(OMX_GetHandle(&pOMXAV->comp[OMXAV_H_VSCHEDULER], "OMX.Nvidia.video.scheduler", pOMXAV, &pOMXAV->callbacks)); @@ -724,14 +822,14 @@ static int AttachVideoRenderer(OMXToolBasicAV_t * pOMXAV) // mandatory before SetupTunnel if(0!=(res=SyncOnState(pOMXAV->comp[OMXAV_H_VSCHEDULER], OMX_StateLoaded))) { - java_throwNewRuntimeException(NULL, "Loading VideoScheduler Failed (%d)", res); + java_throwNewRuntimeException(pOMXAV->jni_env, "Loading VideoScheduler Failed (%d)", res); return res; } // mandatory before EGLUseImage OMXSAFE(RequestState(pOMXAV->comp[OMXAV_H_VSCHEDULER], OMX_StateIdle, KD_FALSE)); DBG_PRINT( "Attach VR %p c:%p\n", pOMXAV, pOMXAV->comp[OMXAV_H_VSCHEDULER]); - OMXSAFE(UpdateStreamInfo(pOMXAV)); + OMXSAFE(UpdateStreamInfo(pOMXAV, KD_FALSE)); DBG_PRINT( "UseEGLImg port enable/tunneling %p\n", pOMXAV); OMXSAFE(OMX_SendCommand(pOMXAV->comp[OMXAV_H_CLOCK], OMX_CommandPortEnable, PORT_VRENDERER, 0)); @@ -744,12 +842,12 @@ static int AttachVideoRenderer(OMXToolBasicAV_t * pOMXAV) for (i = 0; i < pOMXAV->vBufferNum; i++) { OMXToolImageBuffer_t *pBuf = &pOMXAV->buffers[i]; // The Texture, EGLImage and EGLSync was created by the Java client, - // and registered using the OMXToolBasicAV_SetEGLImageTexture2D command. + // and registered using the OMXToolBasicAV_SetStreamEGLImageTexture2D command. DBG_PRINT( "UseEGLImg %p #%d t:%d i:%p s:%p p1\n", pOMXAV, i, pBuf->tex, pBuf->image, pBuf->sync); if(NULL==pBuf->image) { - java_throwNewRuntimeException(NULL, "AttachVideoRenderer: User didn't set buffer %d/%d\n", i, pOMXAV->vBufferNum); + java_throwNewRuntimeException(pOMXAV->jni_env, "AttachVideoRenderer: User didn't set buffer %d/%d\n", i, pOMXAV->vBufferNum); return -1; } else { // tell decoder output port that it will be using EGLImage @@ -774,7 +872,7 @@ static int DetachVideoRenderer(OMXToolBasicAV_t * pOMXAV) if(NULL==pOMXAV) return -1; if(KD_NULL==pOMXAV->comp[OMXAV_H_VSCHEDULER]) { - java_throwNewRuntimeException(NULL, "Attach Video first"); + java_throwNewRuntimeException(pOMXAV->jni_env, "Attach Video first"); return -1; } DBG_PRINT( "DetachVideoRenderer p0\n"); @@ -813,16 +911,12 @@ static int DetachVideoRenderer(OMXToolBasicAV_t * pOMXAV) return 0; } -OMXToolBasicAV_t * OMXToolBasicAV_CreateInstance(int vBufferNum) +OMXToolBasicAV_t * OMXToolBasicAV_CreateInstance() { int i; OMXToolBasicAV_t * pOMXAV = NULL; InitStatic(); - if(vBufferNum>EGLIMAGE_MAX_BUFFERS) { - DBG_PRINT( "buffer number %d > MAX(%d)\n", vBufferNum, EGLIMAGE_MAX_BUFFERS); - return NULL; - } pOMXAV = malloc(sizeof(OMXToolBasicAV_t)); if(NULL==pOMXAV) { DBG_PRINT( "Init struct failed!\n"); @@ -844,14 +938,13 @@ OMXToolBasicAV_t * OMXToolBasicAV_CreateInstance(int vBufferNum) pOMXAV->mutex = kdThreadMutexCreate(KD_NULL); pOMXAV->flushSem = kdThreadSemCreate(0); - pOMXAV->vBufferNum = vBufferNum; - + pOMXAV->play_speed = 1.0f; pOMXAV->status=OMXAV_INIT; return pOMXAV; } -int OMXToolBasicAV_SetStream(OMXToolBasicAV_t * pOMXAV, const KDchar * stream) +void OMXToolBasicAV_SetStream(OMXToolBasicAV_t * pOMXAV, int vBufferNum, const KDchar * stream) { OMX_ERRORTYPE eError = OMX_ErrorNone; @@ -859,22 +952,28 @@ int OMXToolBasicAV_SetStream(OMXToolBasicAV_t * pOMXAV, const KDchar * stream) // FIXME: verify player state .. ie stop ! if(pOMXAV->status!=OMXAV_INIT) { - java_throwNewRuntimeException(NULL, "Player instance in use\n"); - return -1; + java_throwNewRuntimeException(pOMXAV->jni_env, "Player instance in use\n"); + return; + } + if(vBufferNum>EGLIMAGE_MAX_BUFFERS) { + java_throwNewRuntimeException(pOMXAV->jni_env, "buffer number %d > MAX(%d)\n", vBufferNum, EGLIMAGE_MAX_BUFFERS); + return; } kdThreadMutexLock(pOMXAV->mutex); DBG_PRINT( "SetStream 3\n"); + pOMXAV->vBufferNum = vBufferNum; + // Use the "super parser" :) FIXME: Non NV case .. eError = OMX_GetHandle(&pOMXAV->comp[OMXAV_H_READER], "OMX.Nvidia.reader", pOMXAV, &pOMXAV->callbacks); eError = AddFile(pOMXAV, stream); if(eError!=OMX_ErrorNone) { - java_throwNewRuntimeException(NULL, "Couldn't open or handle stream: %s\n", stream); + java_throwNewRuntimeException(pOMXAV->jni_env, "Couldn't open or handle stream: %s\n", stream); kdThreadMutexUnlock(pOMXAV->mutex); - return -1; + return; } DBG_PRINT( "SetStream 4\n"); @@ -886,14 +985,14 @@ int OMXToolBasicAV_SetStream(OMXToolBasicAV_t * pOMXAV, const KDchar * stream) oPortDef.nPortIndex = 0; pOMXAV->videoPort = -1; pOMXAV->audioPort = -1; - OMXSAFE(OMX_GetParameter(pOMXAV->comp[OMXAV_H_READER], OMX_IndexParamPortDefinition, &oPortDef)); + OMXSAFEVOID(OMX_GetParameter(pOMXAV->comp[OMXAV_H_READER], OMX_IndexParamPortDefinition, &oPortDef)); if (oPortDef.eDomain == OMX_PortDomainAudio) pOMXAV->audioPort = oPortDef.nPortIndex; else if (oPortDef.eDomain == OMX_PortDomainVideo) pOMXAV->videoPort = oPortDef.nPortIndex; else - OMXSAFE(OMX_ErrorNotImplemented); + OMXSAFEVOID(OMX_ErrorNotImplemented); INIT_PARAM(oPortDef); oPortDef.nPortIndex = 1; @@ -904,35 +1003,35 @@ int OMXToolBasicAV_SetStream(OMXToolBasicAV_t * pOMXAV, const KDchar * stream) else if (oPortDef.eDomain == OMX_PortDomainVideo) pOMXAV->videoPort = oPortDef.nPortIndex; else - OMXSAFE(OMX_ErrorNotImplemented); + OMXSAFEVOID(OMX_ErrorNotImplemented); } if (pOMXAV->audioPort != -1) { - if (ProbePort(pOMXAV, pOMXAV->audioPort, pOMXAV->audioCodec) != OMX_ErrorNone) + if (ProbePort(pOMXAV, pOMXAV->audioPort, pOMXAV->audioCodec, pOMXAV->audioCodecComponent) != OMX_ErrorNone) { printf("disabling audio port\n"); - OMXSAFE(OMX_SendCommand(pOMXAV->comp[OMXAV_H_READER], OMX_CommandPortDisable, pOMXAV->audioPort, 0)); + OMXSAFEVOID(OMX_SendCommand(pOMXAV->comp[OMXAV_H_READER], OMX_CommandPortDisable, pOMXAV->audioPort, 0)); pOMXAV->audioPort = -1; } } if (pOMXAV->videoPort != -1) - if (ProbePort(pOMXAV, pOMXAV->videoPort, pOMXAV->videoCodec) != OMX_ErrorNone) + if (ProbePort(pOMXAV, pOMXAV->videoPort, pOMXAV->videoCodec, pOMXAV->videoCodecComponent) != OMX_ErrorNone) { printf("disabling video port\n"); - OMXSAFE(OMX_SendCommand(pOMXAV->comp[OMXAV_H_READER], OMX_CommandPortDisable, pOMXAV->videoPort, 0)); + OMXSAFEVOID(OMX_SendCommand(pOMXAV->comp[OMXAV_H_READER], OMX_CommandPortDisable, pOMXAV->videoPort, 0)); pOMXAV->videoPort = -1; } if (pOMXAV->audioPort == -1 && pOMXAV->videoPort == -1) { - java_throwNewRuntimeException(NULL, "Neither audioport or videoport could be played back!\n"); + java_throwNewRuntimeException(pOMXAV->jni_env, "Neither audioport or videoport could be played back!\n"); kdThreadMutexUnlock(pOMXAV->mutex); - return -1; + return; } } DBG_PRINT( "SetStream 5 ; audioPort %d, videoPort %d\n", pOMXAV->audioPort, pOMXAV->videoPort); - OMXSAFE(OMX_GetHandle(&pOMXAV->comp[OMXAV_H_CLOCK], "OMX.Nvidia.clock.component", pOMXAV, &pOMXAV->callbacks)); + OMXSAFEVOID(OMX_GetHandle(&pOMXAV->comp[OMXAV_H_CLOCK], "OMX.Nvidia.clock.component", pOMXAV, &pOMXAV->callbacks)); DBG_PRINT( "Configuring comp[OMXAV_H_CLOCK]\n"); { @@ -941,34 +1040,29 @@ int OMXToolBasicAV_SetStream(OMXToolBasicAV_t * pOMXAV, const KDchar * stream) INIT_PARAM(oActiveClockType); oActiveClockType.eClock = (pOMXAV->audioPort != -1) ? OMX_TIME_RefClockAudio : OMX_TIME_RefClockVideo; - OMXSAFE(OMX_SetConfig(pOMXAV->comp[OMXAV_H_CLOCK], OMX_IndexConfigTimeActiveRefClock, + OMXSAFEVOID(OMX_SetConfig(pOMXAV->comp[OMXAV_H_CLOCK], OMX_IndexConfigTimeActiveRefClock, &oActiveClockType)); } - OMXSAFE(OMX_SendCommand(pOMXAV->comp[OMXAV_H_CLOCK], OMX_CommandPortDisable, (OMX_U32) -1, 0)); + OMXSAFEVOID(OMX_SendCommand(pOMXAV->comp[OMXAV_H_CLOCK], OMX_CommandPortDisable, (OMX_U32) -1, 0)); - OMXSAFE(UpdateStreamInfo(pOMXAV)); + OMXSAFEVOID(UpdateStreamInfo(pOMXAV, KD_FALSE)); kdThreadMutexUnlock(pOMXAV->mutex); DBG_PRINT( "SetStream X\n"); - - return 0; -} - -int OMXToolBasicAV_UpdateStreamInfo(OMXToolBasicAV_t * pOMXAV) { - if(NULL==pOMXAV) return -1; - kdThreadMutexLock(pOMXAV->mutex); - OMXSAFE(UpdateStreamInfo(pOMXAV)); - kdThreadMutexUnlock(pOMXAV->mutex); - return 0; } -int OMXToolBasicAV_SetEGLImageTexture2D(OMXToolBasicAV_t * pOMXAV, KDint i, GLuint tex, EGLImageKHR image, EGLSyncKHR sync) +void OMXToolBasicAV_SetStreamEGLImageTexture2D(OMXToolBasicAV_t * pOMXAV, KDint i, GLuint tex, EGLImageKHR image, EGLSyncKHR sync) { - if(NULL==pOMXAV) return -1; - DBG_PRINT( "SetEGLImg %p #%d/%d t:%d i:%p s:%p..\n", pOMXAV, i, pOMXAV->vBufferNum, tex, image, sync); - if(i<0||i>=pOMXAV->vBufferNum) return -1; - + if(NULL==pOMXAV) { + java_throwNewRuntimeException(0, "OMX instance null\n"); + return; + } + DBG_PRINT( "SetStreamEGLImg %p #%d/%d t:%d i:%p s:%p..\n", pOMXAV, i, pOMXAV->vBufferNum, tex, image, sync); + if(i<0||i>=pOMXAV->vBufferNum) { + java_throwNewRuntimeException(pOMXAV->jni_env, "Buffer index out of range: %d\n", i); + return; + } kdThreadMutexLock(pOMXAV->mutex); { @@ -979,41 +1073,42 @@ int OMXToolBasicAV_SetEGLImageTexture2D(OMXToolBasicAV_t * pOMXAV, KDint i, GLui } kdThreadMutexUnlock(pOMXAV->mutex); - - return 0; } -int OMXToolBasicAV_ActivateInstance(OMXToolBasicAV_t * pOMXAV) { +void OMXToolBasicAV_ActivateStream(OMXToolBasicAV_t * pOMXAV) { int res; - if(NULL==pOMXAV) return -1; - DBG_PRINT( "ActivateInstance 1\n"); + if(NULL==pOMXAV) { + java_throwNewRuntimeException(0, "OMX instance null\n"); + return; + } + DBG_PRINT( "ActivateStream 1\n"); kdThreadMutexLock(pOMXAV->mutex); if (pOMXAV->audioPort != -1) { - OMXSAFE(OMX_GetHandle(&pOMXAV->comp[OMXAV_H_ADECODER], pOMXAV->audioCodec, pOMXAV, &pOMXAV->callbacks)); + OMXSAFEVOID(OMX_GetHandle(&pOMXAV->comp[OMXAV_H_ADECODER], pOMXAV->audioCodecComponent, pOMXAV, &pOMXAV->callbacks)); } if (pOMXAV->videoPort != -1) { - OMXSAFE(OMX_GetHandle(&pOMXAV->comp[OMXAV_H_VDECODER], pOMXAV->videoCodec, pOMXAV, &pOMXAV->callbacks)); + OMXSAFEVOID(OMX_GetHandle(&pOMXAV->comp[OMXAV_H_VDECODER], pOMXAV->videoCodecComponent, pOMXAV, &pOMXAV->callbacks)); } // // mandatory: before SetupTunnel (->Activate), wait until all devices are ready .. // arender/vrender must wait as well .. if(0!=(res=OMXToolBasicAV_WaitForState(pOMXAV, OMX_StateLoaded))) { - java_throwNewRuntimeException(NULL, "Loaded Failed (%d)", res); + java_throwNewRuntimeException(pOMXAV->jni_env, "Loaded Failed (%d)", res); kdThreadMutexUnlock(pOMXAV->mutex); - return res; + return; } if (pOMXAV->audioPort != -1) { if(0!=(res=AttachAudioRenderer(pOMXAV))) { kdThreadMutexUnlock(pOMXAV->mutex); - return res; + return; // exception thrown } } @@ -1021,7 +1116,7 @@ int OMXToolBasicAV_ActivateInstance(OMXToolBasicAV_t * pOMXAV) { { if(0!=(res=AttachVideoRenderer(pOMXAV))) { kdThreadMutexUnlock(pOMXAV->mutex); - return res; + return; // exception thrown } } @@ -1031,18 +1126,18 @@ int OMXToolBasicAV_ActivateInstance(OMXToolBasicAV_t * pOMXAV) { if (pOMXAV->audioPort != -1) { DBG_PRINT( "Setup tunneling audio\n"); - OMXSAFE(OMX_SetupTunnel(pOMXAV->comp[OMXAV_H_READER], pOMXAV->audioPort, pOMXAV->comp[OMXAV_H_ADECODER], 0)); + OMXSAFEVOID(OMX_SetupTunnel(pOMXAV->comp[OMXAV_H_READER], pOMXAV->audioPort, pOMXAV->comp[OMXAV_H_ADECODER], 0)); // The rest of the audio port is configured in AttachAudioRenderer } if (pOMXAV->videoPort != -1) { DBG_PRINT( "Setup tunneling video\n"); - OMXSAFE(OMX_SetupTunnel(pOMXAV->comp[OMXAV_H_READER], pOMXAV->videoPort, pOMXAV->comp[OMXAV_H_VDECODER], 0)); + OMXSAFEVOID(OMX_SetupTunnel(pOMXAV->comp[OMXAV_H_READER], pOMXAV->videoPort, pOMXAV->comp[OMXAV_H_VDECODER], 0)); // The rest of the video port is configured in AttachVideoRenderer } } - DBG_PRINT( "ActivateInstance .. %p\n", pOMXAV); + DBG_PRINT( "ActivateStream .. %p\n", pOMXAV); // // mandatory: wait until all devices are idle @@ -1050,139 +1145,127 @@ int OMXToolBasicAV_ActivateInstance(OMXToolBasicAV_t * pOMXAV) { // if(0!=(res=OMXToolBasicAV_RequestState(pOMXAV, OMX_StateIdle, KD_TRUE))) { - java_throwNewRuntimeException(NULL, "Wait for Idle Failed (%d)", res); + java_throwNewRuntimeException(pOMXAV->jni_env, "Wait for Idle Failed (%d)", res); kdThreadMutexUnlock(pOMXAV->mutex); - return res; + return; } pOMXAV->status=OMXAV_STOPPED; kdThreadMutexUnlock(pOMXAV->mutex); - DBG_PRINT( "ActivateInstance done %p\n", pOMXAV); - return 0; + DBG_PRINT( "ActivateStream done %p\n", pOMXAV); } -int OMXToolBasicAV_DetachVideoRenderer(OMXToolBasicAV_t * pOMXAV) { - int res; - if(NULL==pOMXAV) return -1; +void OMXToolBasicAV_DetachVideoRenderer(OMXToolBasicAV_t * pOMXAV) { + if(NULL==pOMXAV) { + java_throwNewRuntimeException(0, "OMX instance null\n"); + return; + } if(pOMXAV->status<=OMXAV_INIT) { - fprintf(stderr, "Err: DetachVideoRenderer invalid"); - return -1; + java_throwNewRuntimeException(pOMXAV->jni_env, "OMX invalid status: %d <= INIT\n", pOMXAV->status); + return; } - kdThreadMutexLock(pOMXAV->mutex); - res = DetachVideoRenderer(pOMXAV); + (void) DetachVideoRenderer(pOMXAV); kdThreadMutexUnlock(pOMXAV->mutex); - return res; } -int OMXToolBasicAV_AttachVideoRenderer(OMXToolBasicAV_t * pOMXAV) { - int res; - if(NULL==pOMXAV) return -1; +void OMXToolBasicAV_AttachVideoRenderer(OMXToolBasicAV_t * pOMXAV) { + if(NULL==pOMXAV) { + java_throwNewRuntimeException(0, "OMX instance null\n"); + return; + } if(pOMXAV->status<=OMXAV_INIT) { - fprintf(stderr, "Err: AttachVideoRenderer invalid"); - return -1; + java_throwNewRuntimeException(pOMXAV->jni_env, "OMX invalid status: %d <= INIT\n", pOMXAV->status); + return; } - kdThreadMutexLock(pOMXAV->mutex); - res = AttachVideoRenderer(pOMXAV); + (void) AttachVideoRenderer(pOMXAV); kdThreadMutexUnlock(pOMXAV->mutex); - return res; } -int OMXToolBasicAV_SetClockScale(OMXToolBasicAV_t * pOMXAV, KDfloat32 scale) +void OMXToolBasicAV_SetPlaySpeed(OMXToolBasicAV_t * pOMXAV, KDfloat32 scale) { - int res; - if(NULL==pOMXAV) return -1; + if(NULL==pOMXAV) { + java_throwNewRuntimeException(0, "OMX instance null\n"); + return; + } if(pOMXAV->status<=OMXAV_INIT) { - fprintf(stderr, "Err: SetClockScale invalid"); - return -1; + java_throwNewRuntimeException(pOMXAV->jni_env, "OMX invalid status: %d <= INIT\n", pOMXAV->status); + return; } - kdThreadMutexLock(pOMXAV->mutex); - res = SetClockScale(pOMXAV, scale); + if(!SetClockScale(pOMXAV, scale)) { + pOMXAV->play_speed=scale; + } kdThreadMutexUnlock(pOMXAV->mutex); - return res; } -int OMXToolBasicAV_PlayStart(OMXToolBasicAV_t * pOMXAV) +void OMXToolBasicAV_PlayStart(OMXToolBasicAV_t * pOMXAV) { int res; - if(NULL==pOMXAV) return -1; + if(NULL==pOMXAV) { + java_throwNewRuntimeException(0, "OMX instance null\n"); + return; + } if(pOMXAV->status<=OMXAV_INIT) { - fprintf(stderr, "Err: Play invalid"); - return -1; + java_throwNewRuntimeException(pOMXAV->jni_env, "OMX invalid status: %d <= INIT\n", pOMXAV->status); + return; } if(pOMXAV->status==OMXAV_PLAYING) { - return 0; + return; } - DBG_PRINT( "Play 1\n"); kdThreadMutexLock(pOMXAV->mutex); DBG_PRINT( "Play 2\n"); - if(OMXToolBasicAV_CheckState(pOMXAV, OMX_StateIdle)) { - if(0!=(res=OMXToolBasicAV_RequestState(pOMXAV, OMX_StateIdle, KD_TRUE))) { - java_throwNewRuntimeException(NULL, "Idle Failed (%d)", res); - kdThreadMutexUnlock(pOMXAV->mutex); - return res; - } - } - if(pOMXAV->status==OMXAV_PAUSED) { - DBG_PRINT( "Play 3.0\n"); - SetClockScale(pOMXAV, 1); - } + SetClockScale(pOMXAV, pOMXAV->play_speed); + DBG_PRINT( "Play 3.1\n"); if(0!=(res=OMXToolBasicAV_RequestState(pOMXAV, OMX_StateExecuting, KD_TRUE))) { - java_throwNewRuntimeException(NULL, "Play Execute Failed (%d)", res); + java_throwNewRuntimeException(pOMXAV->jni_env, "Play Execute Failed (%d)", res); kdThreadMutexUnlock(pOMXAV->mutex); - return res; + return; } if(pOMXAV->status==OMXAV_STOPPED || pOMXAV->status==OMXAV_FIN) { DBG_PRINT( "Play 3.2\n"); if(StartClock(pOMXAV, KD_TRUE, 0.0)) { - java_throwNewRuntimeException(NULL, "Play StartClock Failed"); + java_throwNewRuntimeException(pOMXAV->jni_env, "Play StartClock Failed"); kdThreadMutexUnlock(pOMXAV->mutex); - return -1; + return; } - DBG_PRINT( "Play 3.3\n"); } DBG_PRINT( "Play 4.0\n"); kdThreadMutexUnlock(pOMXAV->mutex); pOMXAV->status=OMXAV_PLAYING; DBG_PRINT( "Play DONE\n"); - return 0; } static int PlayStop(OMXToolBasicAV_t * pOMXAV) { int res; - if(NULL==pOMXAV) return -1; - - if(pOMXAV->status<=OMXAV_INIT) { - fprintf(stderr, "Err: Stop invalid"); + if(NULL==pOMXAV || pOMXAV->status<=OMXAV_INIT) { return -1; } if( pOMXAV->status!=OMXAV_PLAYING && pOMXAV->status!=OMXAV_PAUSED ) { - fprintf(stderr, "Err: Stop not playing nor paused"); return -1; } if(OMXToolBasicAV_CheckState(pOMXAV, OMX_StateLoaded)) { if(StartClock(pOMXAV, KD_FALSE, 0.0)) { - java_throwNewRuntimeException(NULL, "Stop StopClock Failed"); + java_throwNewRuntimeException(pOMXAV->jni_env, "Stop StopClock Failed"); kdThreadMutexUnlock(pOMXAV->mutex); return -1; } if(OMXToolBasicAV_CheckState(pOMXAV, OMX_StateIdle)) { if(0!=(res=OMXToolBasicAV_RequestState(pOMXAV, OMX_StateIdle, KD_TRUE))) { - java_throwNewRuntimeException(NULL, "Stop Idle Failed (%d)", res); + java_throwNewRuntimeException(pOMXAV->jni_env, "Stop Idle Failed (%d)", res); kdThreadMutexUnlock(pOMXAV->mutex); return res; } @@ -1192,31 +1275,36 @@ static int PlayStop(OMXToolBasicAV_t * pOMXAV) return 0; } -int OMXToolBasicAV_PlayStop(OMXToolBasicAV_t * pOMXAV) +void OMXToolBasicAV_PlayStop(OMXToolBasicAV_t * pOMXAV) { - int res; - if(NULL==pOMXAV) return -1; - + if(NULL==pOMXAV) { + java_throwNewRuntimeException(0, "OMX instance null\n"); + return; + } + if(pOMXAV->status<=OMXAV_INIT) { + java_throwNewRuntimeException(pOMXAV->jni_env, "OMX invalid status: %d <= INIT\n", pOMXAV->status); + return; + } kdThreadMutexLock(pOMXAV->mutex); - res=PlayStop(pOMXAV); + + (void) PlayStop(pOMXAV); + kdThreadMutexUnlock(pOMXAV->mutex); - return res; } -int OMXToolBasicAV_PlayPause(OMXToolBasicAV_t * pOMXAV) +void OMXToolBasicAV_PlayPause(OMXToolBasicAV_t * pOMXAV) { int res; - if(NULL==pOMXAV) return -1; - if(pOMXAV->status<=OMXAV_INIT) { - fprintf(stderr, "Err: Pause invalid"); - return -1; + if(NULL==pOMXAV) { + java_throwNewRuntimeException(0, "OMX instance null\n"); + return; } - if(pOMXAV->status==OMXAV_PAUSED) { - return 0; + if(pOMXAV->status<=OMXAV_INIT) { + java_throwNewRuntimeException(pOMXAV->jni_env, "OMX invalid status: %d <= INIT\n", pOMXAV->status); + return; } - if(pOMXAV->status!=OMXAV_PLAYING) { - fprintf(stderr, "Err: Pause not playing"); - return -1; + if(pOMXAV->status==OMXAV_PAUSED || pOMXAV->status!=OMXAV_PLAYING) { + return; } kdThreadMutexLock(pOMXAV->mutex); @@ -1224,33 +1312,40 @@ int OMXToolBasicAV_PlayPause(OMXToolBasicAV_t * pOMXAV) if(0!=(res=OMXToolBasicAV_RequestState(pOMXAV, OMX_StatePause, KD_TRUE))) { fprintf(stderr, "Err: Pause Pause Failed (%d)", res); kdThreadMutexUnlock(pOMXAV->mutex); - return res; + return; } pOMXAV->status=OMXAV_PAUSED; kdThreadMutexUnlock(pOMXAV->mutex); - return 0; } -int OMXToolBasicAV_PlaySeek(OMXToolBasicAV_t * pOMXAV, KDfloat32 time) +void OMXToolBasicAV_PlaySeek(OMXToolBasicAV_t * pOMXAV, KDfloat32 time) { int res; - OMX_ERRORTYPE eError = OMX_ErrorNotReady; - if(NULL==pOMXAV) return -1; + if(NULL==pOMXAV) { + java_throwNewRuntimeException(0, "OMX instance null\n"); + return; + } if(pOMXAV->status<=OMXAV_INIT) { - fprintf(stderr, "Err: Seek invalid"); - return -1; + java_throwNewRuntimeException(pOMXAV->jni_env, "OMX invalid status: %d <= INIT\n", pOMXAV->status); + return; } - kdThreadMutexLock(pOMXAV->mutex); + pOMXAV->length = GetMediaLength(pOMXAV); + if(pOMXAV->length<=time) { + (void) PlayStop(pOMXAV); + kdThreadMutexUnlock(pOMXAV->mutex); + return; + } + // 1. Pause the component through the use of OMX_SendCommand requesting a // state transition to OMX_StatePause. if(pOMXAV->status!=OMXAV_PAUSED) { if(0!=(res=OMXToolBasicAV_RequestState(pOMXAV, OMX_StatePause, KD_TRUE))) { - fprintf(stderr, "Err: Seek Pause Failed (%d)", res); + java_throwNewRuntimeException(pOMXAV->jni_env, "Seek Pause Failed (%d)", res); kdThreadMutexUnlock(pOMXAV->mutex); - return res; + return; } } @@ -1258,39 +1353,24 @@ int OMXToolBasicAV_PlaySeek(OMXToolBasicAV_t * pOMXAV, KDfloat32 time) // on OMX_TIME_CONFIG_CLOCKSTATETYPE requesting a transition to // OMX_TIME_ClockStateStopped. if(StartClock(pOMXAV, KD_FALSE, 0.0)) { - java_throwNewRuntimeException(NULL, "Seek StopClock Failed"); + java_throwNewRuntimeException(pOMXAV->jni_env, "Seek StopClock Failed"); kdThreadMutexUnlock(pOMXAV->mutex); - return -1; + return; } // 3. Seek to the desired location through the use of OMX_SetConfig on // OMX_IndexConfigTimePosition requesting the desired timestamp. - { - OMX_TIME_CONFIG_TIMESTAMPTYPE timestamp; - int loop=STATE_TIMEOUT_LOOP; - INIT_PARAM(timestamp); - timestamp.nPortIndex = 0; - timestamp.nTimestamp = (OMX_TICKS) (time * 1000.0 * 1000.0); - - eError = OMX_SetConfig(pOMXAV->comp[OMXAV_H_READER], OMX_IndexConfigTimePosition, ×tamp); - while (loop>0 && OMX_ErrorNotReady == eError) - { - usleep(STATE_SLEEP*1000); - loop--; - eError = OMX_SetConfig(pOMXAV->comp[OMXAV_H_READER], OMX_IndexConfigTimePosition, ×tamp); - } - if (OMX_ErrorNotReady == eError) { - java_throwNewRuntimeException(NULL, "Seek position Failed"); - kdThreadMutexUnlock(pOMXAV->mutex); - return -1; - } + if(SetMediaPosition(pOMXAV, time)) { + java_throwNewRuntimeException(pOMXAV->jni_env, "Seek position Failed"); + kdThreadMutexUnlock(pOMXAV->mutex); + return; } // 4. Flush all components. if(SendCommand(pOMXAV, OMX_CommandFlush, OMX_ALL, 0)) { - fprintf(stderr, "Err: Seek Flush Failed"); + java_throwNewRuntimeException(pOMXAV->jni_env, "Seek Flush Failed"); kdThreadMutexUnlock(pOMXAV->mutex); - return -1; + return; } // 5. Start the comp[OMXAV_H_CLOCK] components media comp[OMXAV_H_CLOCK] through the use of OMX_SetConfig @@ -1298,25 +1378,24 @@ int OMXToolBasicAV_PlaySeek(OMXToolBasicAV_t * pOMXAV, KDfloat32 time) // OMX_TIME_ClockStateRunning or // OMX_TIME_ClockStateWaitingForStartTime. if(StartClock(pOMXAV, KD_TRUE, time)) { - java_throwNewRuntimeException(NULL, "Seek StartClock Failed"); + java_throwNewRuntimeException(pOMXAV->jni_env, "Seek StartClock Failed"); kdThreadMutexUnlock(pOMXAV->mutex); - return -1; + return; } // 6. Un-pause the component through the use of OMX_SendCommand requesting a // state transition to OMX_StateExecuting. - if(pOMXAV->status!=OMXAV_PLAYING) { + if(pOMXAV->status==OMXAV_PLAYING) { if(0!=(res=OMXToolBasicAV_RequestState(pOMXAV, OMX_StateExecuting, KD_TRUE))) { - fprintf(stderr, "Err: Seek Execute Failed (%d)", res); + java_throwNewRuntimeException(pOMXAV->jni_env, "Seek Execute Failed (%d)", res); kdThreadMutexUnlock(pOMXAV->mutex); - return res; + return; } } kdThreadMutexUnlock(pOMXAV->mutex); - return 0; } -GLuint OMXToolBasicAV_GetTexture(OMXToolBasicAV_t * pOMXAV) { +GLuint OMXToolBasicAV_GetNextTextureID(OMXToolBasicAV_t * pOMXAV) { GLuint texID = 0; int ret = pOMXAV->glPos; kdThreadMutexLock(pOMXAV->mutex); @@ -1324,7 +1403,7 @@ GLuint OMXToolBasicAV_GetTexture(OMXToolBasicAV_t * pOMXAV) { if(pOMXAV->status==OMXAV_PLAYING) { int next = (pOMXAV->omxPos + 1) % pOMXAV->vBufferNum; - DBG_PRINT2("GetTexture A avail %d, filled %d, pos o:%d g:%d\n", + DBG_PRINT2("GetNextTexture A avail %d, filled %d, pos o:%d g:%d\n", pOMXAV->available, pOMXAV->filled, pOMXAV->omxPos, pOMXAV->glPos); while (pOMXAV->filled < pOMXAV->vBufferNum) @@ -1335,25 +1414,25 @@ GLuint OMXToolBasicAV_GetTexture(OMXToolBasicAV_t * pOMXAV) { attr == EGL_SIGNALED_KHR ) ) { - DBG_PRINT2( "GetTexture p2.1 attr 0x%X\n", attr); + DBG_PRINT2( "GetNextTexture p2.1 attr 0x%X\n", attr); // OpenGL has finished rendering with this texture, so we are free // to make OpenMAX IL fill it with new data. OMX_FillThisBuffer(pOMXAV->comp[OMXAV_H_VSCHEDULER], pOMXAV->buffers[pOMXAV->omxPos].omxBufferHeader); - DBG_PRINT2( "GetTexture p2.2\n"); + DBG_PRINT2( "GetNextTexture p2.2\n"); pOMXAV->omxPos = next; next = (pOMXAV->omxPos + 1) % pOMXAV->vBufferNum; pOMXAV->filled++; } else { - DBG_PRINT2( "GetTexture p2.3\n"); + DBG_PRINT2( "GetNextTexture p2.3\n"); break; } } } if (pOMXAV->available > 1) { - DBG_PRINT2("GetTexture p3.1\n"); + DBG_PRINT2("GetNextTexture p3.1\n"); // We want to make sure that the previous eglImage // has finished, so insert a fence command into the // command stream to make sure that any rendering using @@ -1363,7 +1442,7 @@ GLuint OMXToolBasicAV_GetTexture(OMXToolBasicAV_t * pOMXAV) { // was successfull. if (!_hasEGLSync || eglFenceKHR(pOMXAV->buffers[pOMXAV->glPos].sync)) { - DBG_PRINT2( "GetTexture p3.2\n"); + DBG_PRINT2( "GetNextTexture p3.2\n"); pOMXAV->available--; pOMXAV->filled--; pOMXAV->glPos = (pOMXAV->glPos + 1) % pOMXAV->vBufferNum; @@ -1372,13 +1451,32 @@ GLuint OMXToolBasicAV_GetTexture(OMXToolBasicAV_t * pOMXAV) { } texID = pOMXAV->available ? pOMXAV->buffers[ret].tex : 0; - DBG_PRINT2( "GetTexture B avail %d, filled %d, pos o:%d g:%d t:%d\n", + DBG_PRINT2( "GetNextTexture B avail %d, filled %d, pos o:%d g:%d t:%d\n", pOMXAV->available, pOMXAV->filled, pOMXAV->omxPos, pOMXAV->glPos, texID); kdThreadMutexUnlock(pOMXAV->mutex); return texID; } +KDfloat32 OMXToolBasicAV_GetCurrentPosition(OMXToolBasicAV_t * pOMXAV) { + KDfloat32 res = -1.0f; + if(NULL==pOMXAV) { + java_throwNewRuntimeException(0, "OMX instance null\n"); + return res; + } + if(pOMXAV->status<=OMXAV_INIT) { + java_throwNewRuntimeException(pOMXAV->jni_env, "OMX invalid status: %d <= INIT\n", pOMXAV->status); + return res; + } + kdThreadMutexLock(pOMXAV->mutex); + + res = GetClockPosition(pOMXAV); + + kdThreadMutexUnlock(pOMXAV->mutex); + + return res; +} + void OMXToolBasicAV_DestroyInstance(OMXToolBasicAV_t * pOMXAV) { if(NULL==pOMXAV) return; @@ -1548,13 +1646,13 @@ int ModuleTest() printf("6 eglGetError: 0x%x\n", eglGetError()); - if(OMXToolBasicAV_SetEGLImageTexture2D(pOMXAV, i, tex, image, sync)) { + if(OMXToolBasicAV_SetStreamEGLImageTexture2D(pOMXAV, i, tex, image, sync)) { return -1; } } printf("7\n"); - if( OMXToolBasicAV_ActivateInstance(pOMXAV) ) { + if( OMXToolBasicAV_ActivateStream(pOMXAV) ) { return -1; } diff --git a/src/native/openmax/omx_tool.h b/src/native/openmax/omx_tool.h index abfe09eff..9c0df93b3 100644 --- a/src/native/openmax/omx_tool.h +++ b/src/native/openmax/omx_tool.h @@ -86,11 +86,18 @@ typedef struct { OMX_CALLBACKTYPE callbacks; KDchar audioCodec[256]; + KDchar audioCodecComponent[256]; KDchar videoCodec[256]; + KDchar videoCodecComponent[256]; int audioPort; int videoPort; - int width; - int height; + KDuint32 width; + KDuint32 height; + KDuint32 bitrate; // per seconds + KDuint32 framerate; // per seconds + KDfloat32 length; // seconds + KDfloat32 speed; // current clock scale + KDfloat32 play_speed; // current play clock scale KDThreadMutex * mutex; KDThreadSem * flushSem; @@ -103,6 +110,18 @@ typedef struct { int available; int status; + + intptr_t jni_env; + intptr_t jni_instance; + intptr_t jni_mid_saveAttributes; + intptr_t jni_mid_attributesUpdated; + intptr_t jni_fid_width; + intptr_t jni_fid_height; + intptr_t jni_fid_fps; + intptr_t jni_fid_bps; + intptr_t jni_fid_totalFrames; + intptr_t jni_fid_acodec; + intptr_t jni_fid_vcodec; } OMXToolBasicAV_t ; // @@ -119,27 +138,28 @@ KDint OMXToolBasicAV_SetState(OMXToolBasicAV_t * pOMXAV, OMX_STATETYPE state, KD // // User related functionality, mutex managed // -OMXToolBasicAV_t * OMXToolBasicAV_CreateInstance(int vBufferNum); // #1 -int OMXToolBasicAV_SetStream(OMXToolBasicAV_t * pOMXAV, const KDchar * stream); // #3 -int OMXToolBasicAV_UpdateStreamInfo(OMXToolBasicAV_t * pOMXAV); -int OMXToolBasicAV_SetEGLImageTexture2D(OMXToolBasicAV_t * pOMXAV, KDint i, GLuint tex, EGLImageKHR image, EGLSyncKHR sync); // #2.. -int OMXToolBasicAV_ActivateInstance(OMXToolBasicAV_t * pOMXAV); - -int OMXToolBasicAV_AttachVideoRenderer(OMXToolBasicAV_t * pOMXAV); // DetachVideoRenderer before .. -int OMXToolBasicAV_DetachVideoRenderer(OMXToolBasicAV_t * pOMXAV); // Stop before .. - -int OMXToolBasicAV_SetClockScale(OMXToolBasicAV_t * pOMXAV, KDfloat32 scale); -int OMXToolBasicAV_PlayStart(OMXToolBasicAV_t * pOMXAV); -int OMXToolBasicAV_PlayPause(OMXToolBasicAV_t * pOMXAV); -int OMXToolBasicAV_PlayStop(OMXToolBasicAV_t * pOMXAV); -int OMXToolBasicAV_PlaySeek(OMXToolBasicAV_t * pOMXAV, KDfloat32 time); -GLuint OMXToolBasicAV_GetTexture(OMXToolBasicAV_t * pOMXAV); +OMXToolBasicAV_t * OMXToolBasicAV_CreateInstance(); // #1 +void OMXToolBasicAV_SetStream(OMXToolBasicAV_t * pOMXAV, int vBufferNum, const KDchar * stream); // #2 +void OMXToolBasicAV_SetStreamEGLImageTexture2D(OMXToolBasicAV_t * pOMXAV, KDint i, GLuint tex, EGLImageKHR image, EGLSyncKHR sync); // #3 +void OMXToolBasicAV_ActivateStream(OMXToolBasicAV_t * pOMXAV); // #4 -void OMXToolBasicAV_DestroyInstance(OMXToolBasicAV_t * pOMXAV); -int ModuleTest(); +void OMXToolBasicAV_AttachVideoRenderer(OMXToolBasicAV_t * pOMXAV); // Stop, DetachVideoRenderer, SetEGLImageTexture2D .. before .. +void OMXToolBasicAV_DetachVideoRenderer(OMXToolBasicAV_t * pOMXAV); // Stop before .. +void OMXToolBasicAV_SetPlaySpeed(OMXToolBasicAV_t * pOMXAV, KDfloat32 scale); +void OMXToolBasicAV_PlayStart(OMXToolBasicAV_t * pOMXAV); // #5 +void OMXToolBasicAV_PlayPause(OMXToolBasicAV_t * pOMXAV); +void OMXToolBasicAV_PlayStop(OMXToolBasicAV_t * pOMXAV); +void OMXToolBasicAV_PlaySeek(OMXToolBasicAV_t * pOMXAV, KDfloat32 time); +GLuint OMXToolBasicAV_GetNextTextureID(OMXToolBasicAV_t * pOMXAV); +KDfloat32 OMXToolBasicAV_GetCurrentPosition(OMXToolBasicAV_t * pOMXAV); +void OMXToolBasicAV_DestroyInstance(OMXToolBasicAV_t * pOMXAV); + +#if defined(SELF_TEST) + int ModuleTest(); +#endif #endif /* _OMX_TOOL_H */ |