diff options
author | Sven Gothel <[email protected]> | 2014-01-26 04:55:37 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2014-01-26 04:55:37 +0100 |
commit | b92a813063212130d6205a25b1f84662e8c4c0f9 (patch) | |
tree | 295d09ad048f3609df435c49e69c152e6007bf88 | |
parent | 323476249dd94e605b6627582ad0dbcaede0159e (diff) |
Bug 927 - Enhance GLMediaPlayer/FFMPEGMediaPlayer MovieSimple to run multiple instances in parallel
Tested on GNU/Linux x86_64,
Result: Plays well here audio and video, i.e. audio is actually mixed from both movies.
Even if one movie (below) stops and restarts (AL buffer reset),
it didn't crash.
+++
LIB_AV Codec : 54.92.100 [cc 54]
LIB_AV Format : 54.63.104 [cc 54]
LIB_AV Util : 52.18.100 [cc 52]
LIB_AV Resample: 1.0.1 [cc 1, loaded true]
LIB_SW Resample: 0.17.102 [cc 0, loaded true]
LIB_AV Device : [loaded true]
LIB_AV Class : FFMPEGv09Natives
+++
(enable MovieSimple in scripts/tests.sh)
bash scripts/tests-x64.sh -loop -windows 2 \
-urlN 0 http://download.blender.org/peach/bigbuckbunny_movies/big_buck_bunny_720p_surround.avi \
-urlN 1 http://video.webmfiles.org/elephants-dream.webm
+++
2 Streaming threads, i.e. decoder threads:
"Thread-5-StreamWorker_1" daemon prio=10 tid=0x00007f994c102000 nid=0x5826 in Object.wait() [0x00007f996fa37000]
at jogamp.opengl.util.av.GLMediaPlayerImpl$StreamWorker.run(GLMediaPlayerImpl.java:1231)
"Thread-4-StreamWorker_0" daemon prio=10 tid=0x00007f99600ed000 nid=0x5825 in Object.wait() [0x00007f996cd09000]
at jogamp.opengl.util.av.GLMediaPlayerImpl$StreamWorker.run(GLMediaPlayerImpl.java:1231)
-rw-r--r-- | make/scripts/tests.sh | 6 | ||||
-rw-r--r-- | src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java | 287 |
2 files changed, 169 insertions, 124 deletions
diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh index c687c01a0..85eb14252 100644 --- a/make/scripts/tests.sh +++ b/make/scripts/tests.sh @@ -242,7 +242,7 @@ function jrun() { #D_ARGS="-Djogamp.debug.IOUtil -Djogl.debug.GLSLCode -Djogl.debug.GLMediaPlayer" #D_ARGS="-Djogl.debug.GLMediaPlayer -Djogl.debug.AudioSink" #D_ARGS="-Djogl.debug.GLMediaPlayer -Djogl.debug.GLMediaPlayer.Native" - #D_ARGS="-Djogl.debug.GLMediaPlayer" + D_ARGS="-Djogl.debug.GLMediaPlayer" #D_ARGS="-Djogl.debug.GLMediaPlayer.StreamWorker.delay=25 -Djogl.debug.GLMediaPlayer" #D_ARGS="-Djogl.debug.GLMediaPlayer.Native" @@ -355,13 +355,13 @@ function testawtswt() { # #testnoawt jogamp.opengl.openal.av.ALDummyUsage $* #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieCube $* -#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieSimple $* +testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieSimple $* # # performance tests # #testnoawt com.jogamp.opengl.test.junit.jogl.perf.TestPerf001RawInit00NEWT $* -testawt com.jogamp.opengl.test.junit.jogl.perf.TestPerf001GLJPanelInit01AWT $* +#testawt com.jogamp.opengl.test.junit.jogl.perf.TestPerf001GLJPanelInit01AWT $* #testawt com.jogamp.opengl.test.junit.jogl.perf.TestPerf001GLJPanelInit02AWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.perf.TestPerf001GLWindowInit03NEWT $* diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java index ddf5c709c..fcf1cd2ef 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java @@ -36,6 +36,7 @@ import java.nio.FloatBuffer; import javax.media.opengl.GL; import javax.media.opengl.GL2ES2; +import javax.media.opengl.GLAnimatorControl; import javax.media.opengl.GLAutoDrawable; import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLES2; @@ -84,6 +85,9 @@ public class MovieSimple implements GLEventListener { public static final int EFFECT_GRADIENT_BOTTOM2TOP = 1<<1; public static final int EFFECT_TRANSPARENT = 1<<3; + private static final String WINDOW_KEY = "window"; + private static final String PLAYER = "player"; + private static boolean waitForKey = false; private int winWidth, winHeight; private int prevMouseX; // , prevMouseY; @@ -286,6 +290,7 @@ public class MovieSimple implements GLEventListener { mPlayerShared = null != mPlayer; if( !mPlayerShared ) { mPlayer = GLMediaPlayerFactory.createDefault(); + mPlayer.attachObject(PLAYER, this); } System.out.println("pC.1a shared "+mPlayerShared+", "+mPlayer); } @@ -701,6 +706,94 @@ public class MovieSimple implements GLEventListener { st.useProgram(gl, false); } + static class MyGLMediaEventListener implements GLMediaEventListener { + void destroyWindow(final Window window) { + new Thread() { + public void run() { + window.destroy(); + } }.start(); + } + + @Override + public void newFrameAvailable(GLMediaPlayer ts, TextureFrame newFrame, long when) { + } + + @Override + public void attributesChanged(final GLMediaPlayer mp, int event_mask, long when) { + System.err.println("MovieSimple AttributesChanges: events_mask 0x"+Integer.toHexString(event_mask)+", when "+when); + System.err.println("MovieSimple State: "+mp); + final GLWindow window = (GLWindow) mp.getAttachedObject(WINDOW_KEY); + final MovieSimple ms = (MovieSimple)mp.getAttachedObject(PLAYER); + if( 0 != ( GLMediaEventListener.EVENT_CHANGE_SIZE & event_mask ) ) { + System.err.println("MovieSimple State: CHANGE_SIZE"); + if( origSize ) { + window.setSize(mp.getWidth(), mp.getHeight()); + } + // window.disposeGLEventListener(ms, false /* remove */ ); + ms.resetGLState(); + } + if( 0 != ( GLMediaEventListener.EVENT_CHANGE_INIT & event_mask ) ) { + System.err.println("MovieSimple State: INIT"); + // Use GLEventListener in all cases [A+V, V, A] + window.addGLEventListener(ms); + final GLAnimatorControl anim = window.getAnimator(); + anim.setUpdateFPSFrames(60, System.err); + anim.resetFPSCounter(); + + /** + * Kick off player w/o GLEventListener, i.e. for audio only. + * + try { + ms.mPlayer.initGL(null); + } catch (Exception e) { + e.printStackTrace(); + destroyWindow(); + return; + } + ms.mPlayer.play(); + System.out.println("play.1 "+ms.mPlayer); + */ + } + boolean destroy = false; + Throwable err = null; + + if( 0 != ( GLMediaEventListener.EVENT_CHANGE_EOS & event_mask ) ) { + err = ms.mPlayer.getStreamException(); + if( null != err ) { + System.err.println("MovieSimple State: EOS + Exception"); + destroy = true; + } else { + System.err.println("MovieSimple State: EOS"); + if( loopEOS ) { + ms.mPlayer.seek(0); + ms.mPlayer.play(); + } else { + destroy = true; + } + } + } + if( 0 != ( GLMediaEventListener.EVENT_CHANGE_ERR & event_mask ) ) { + err = ms.mPlayer.getStreamException(); + if( null != err ) { + System.err.println("MovieSimple State: ERR + Exception"); + } else { + System.err.println("MovieSimple State: ERR"); + } + destroy = true; + } + if( destroy ) { + if( null != err ) { + err.printStackTrace(); + } + destroyWindow(window); + } + } + }; + final static MyGLMediaEventListener myGLMediaEventListener = new MyGLMediaEventListener(); + + static boolean loopEOS = false; + static boolean origSize; + public static void main(String[] args) throws IOException, URISyntaxException { int swapInterval = 1; int width = 640; @@ -708,7 +801,6 @@ public class MovieSimple implements GLEventListener { int textureCount = 3; // default - threaded boolean ortho = true; boolean zoom = false; - boolean _loopEOS = false; boolean forceES2 = false; boolean forceES3 = false; @@ -716,9 +808,20 @@ public class MovieSimple implements GLEventListener { boolean forceGLDef = false; int vid = GLMediaPlayer.STREAM_ID_AUTO; int aid = GLMediaPlayer.STREAM_ID_AUTO; - final boolean origSize; - String url_s=null, file_s1=null, file_s2=null; + final int windowCount; + { + int _windowCount = 1; + for(int i=0; i<args.length; i++) { + if(args[i].equals("-windows")) { + i++; + _windowCount = MiscUtils.atoi(args[i], _windowCount); + } + } + windowCount = _windowCount; + } + String[] urls_s = new String[windowCount]; + String file_s1=null, file_s2=null; { boolean _origSize = false; for(int i=0; i<args.length; i++) { @@ -755,10 +858,15 @@ public class MovieSimple implements GLEventListener { } else if(args[i].equals("-zoom")) { zoom=true; } else if(args[i].equals("-loop")) { - _loopEOS=true; + loopEOS=true; + } else if(args[i].equals("-urlN")) { + i++; + final int n = MiscUtils.atoi(args[i], 0); + i++; + urls_s[n] = args[i]; } else if(args[i].equals("-url")) { i++; - url_s = args[i]; + urls_s[0] = args[i]; } else if(args[i].equals("-file1")) { i++; file_s1 = args[i]; @@ -771,21 +879,20 @@ public class MovieSimple implements GLEventListener { } origSize = _origSize; } - final boolean loopEOS = _loopEOS; - final URI streamLoc; - if( null != url_s ) { - streamLoc = new URI(url_s); + final URI streamLoc0; + if( null != urls_s[0] ) { + streamLoc0 = new URI(urls_s[0]); } else if( null != file_s1 ) { File movieFile = new File(file_s1); - streamLoc = movieFile.toURI(); + streamLoc0 = movieFile.toURI(); } else if( null != file_s2 ) { - streamLoc = IOUtil.toURISimple(new File(file_s2)); + streamLoc0 = IOUtil.toURISimple(new File(file_s2)); } else { - streamLoc = defURI; + streamLoc0 = defURI; } - System.err.println("url_s "+url_s); + System.err.println("url_s "+urls_s[0]); System.err.println("file_s 1: "+file_s1+", 2: "+file_s2); - System.err.println("stream "+streamLoc); + System.err.println("stream0 "+streamLoc0); System.err.println("vid "+vid+", aid "+aid); System.err.println("textureCount "+textureCount); System.err.println("forceES2 "+forceES2); @@ -794,119 +901,57 @@ public class MovieSimple implements GLEventListener { System.err.println("forceGLDef "+forceGLDef); System.err.println("swapInterval "+swapInterval); - final MovieSimple ms = new MovieSimple(null); - ms.setSwapInterval(swapInterval); - ms.setScaleOrig(!zoom); - ms.setOrthoProjection(ortho); + final GLProfile glp; + if(forceGLDef) { + glp = GLProfile.getDefault(); + } else if(forceGL3) { + glp = GLProfile.get(GLProfile.GL3); + } else if(forceES3) { + glp = GLProfile.get(GLProfile.GLES3); + } else if(forceES2) { + glp = GLProfile.get(GLProfile.GLES2); + } else { + glp = GLProfile.getGL2ES2(); + } + System.err.println("GLProfile: "+glp); + GLCapabilities caps = new GLCapabilities(glp); - try { - final GLProfile glp; - if(forceGLDef) { - glp = GLProfile.getDefault(); - } else if(forceGL3) { - glp = GLProfile.get(GLProfile.GL3); - } else if(forceES3) { - glp = GLProfile.get(GLProfile.GLES3); - } else if(forceES2) { - glp = GLProfile.get(GLProfile.GLES2); - } else { - glp = GLProfile.getGL2ES2(); - } - System.err.println("GLProfile: "+glp); - GLCapabilities caps = new GLCapabilities(glp); - final GLWindow window = GLWindow.create(caps); - final Animator anim = new Animator(window); - window.addWindowListener(new WindowAdapter() { + final Animator anim = new Animator(); + anim.start(); + + final MovieSimple[] mss = new MovieSimple[windowCount]; + final GLWindow[] windows = new GLWindow[windowCount]; + for(int i=0; i<windowCount; i++) { + windows[i] = GLWindow.create(caps); + windows[i].addWindowListener(new WindowAdapter() { public void windowDestroyed(WindowEvent e) { anim.stop(); } }); - window.setSize(width, height); - window.setVisible(true); - anim.start(); - - ms.mPlayer.addEventListener(new GLMediaEventListener() { - void destroyWindow() { - new Thread() { - public void run() { - window.destroy(); - } }.start(); - } - - @Override - public void newFrameAvailable(GLMediaPlayer ts, TextureFrame newFrame, long when) { - } - - @Override - public void attributesChanged(final GLMediaPlayer mp, int event_mask, long when) { - System.err.println("MovieSimple AttributesChanges: events_mask 0x"+Integer.toHexString(event_mask)+", when "+when); - System.err.println("MovieSimple State: "+mp); - if( 0 != ( GLMediaEventListener.EVENT_CHANGE_SIZE & event_mask ) ) { - System.err.println("MovieSimple State: CHANGE_SIZE"); - if( origSize ) { - window.setSize(mp.getWidth(), mp.getHeight()); - } - // window.disposeGLEventListener(ms, false /* remove */ ); - ms.resetGLState(); - } - if( 0 != ( GLMediaEventListener.EVENT_CHANGE_INIT & event_mask ) ) { - System.err.println("MovieSimple State: INIT"); - // Use GLEventListener in all cases [A+V, V, A] - window.addGLEventListener(ms); - anim.setUpdateFPSFrames(60, System.err); - anim.resetFPSCounter(); - /** - * Kick off player w/o GLEventListener, i.e. for audio only. - * - try { - ms.mPlayer.initGL(null); - } catch (Exception e) { - e.printStackTrace(); - destroyWindow(); - return; - } - ms.mPlayer.play(); - System.out.println("play.1 "+ms.mPlayer); - */ - } - boolean destroy = false; - Throwable err = null; - - if( 0 != ( GLMediaEventListener.EVENT_CHANGE_EOS & event_mask ) ) { - err = ms.mPlayer.getStreamException(); - if( null != err ) { - System.err.println("MovieSimple State: EOS + Exception"); - destroy = true; - } else { - System.err.println("MovieSimple State: EOS"); - if( loopEOS ) { - ms.mPlayer.seek(0); - ms.mPlayer.play(); - } else { - destroy = true; - } - } - } - if( 0 != ( GLMediaEventListener.EVENT_CHANGE_ERR & event_mask ) ) { - err = ms.mPlayer.getStreamException(); - if( null != err ) { - System.err.println("MovieSimple State: ERR + Exception"); - } else { - System.err.println("MovieSimple State: ERR"); - } - destroy = true; - } - if( destroy ) { - if( null != err ) { - err.printStackTrace(); - } - destroyWindow(); - } + mss[i] = new MovieSimple(null); + mss[i].setSwapInterval(swapInterval); + mss[i].setScaleOrig(!zoom); + mss[i].setOrthoProjection(ortho); + mss[i].mPlayer.attachObject(WINDOW_KEY, windows[i]); + mss[i].mPlayer.addEventListener(myGLMediaEventListener); + + windows[i].setTitle("Player "+i); + windows[i].setSize(width, height); + windows[i].setVisible(true); + anim.add(windows[i]); + + final URI streamLocN; + if( 0 == i ) { + streamLocN = streamLoc0; + } else { + if( null != urls_s[i] ) { + streamLocN = new URI(urls_s[i]); + } else { + streamLocN = defURI; } - }); - ms.initStream(streamLoc, vid, aid, textureCount); - } catch (Throwable t) { - t.printStackTrace(); + } + System.err.println("Win #"+i+": stream "+streamLocN); + mss[i].initStream(streamLocN, vid, aid, textureCount); } } } |