aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2014-01-26 04:55:37 +0100
committerSven Gothel <[email protected]>2014-01-26 04:55:37 +0100
commitb92a813063212130d6205a25b1f84662e8c4c0f9 (patch)
tree295d09ad048f3609df435c49e69c152e6007bf88
parent323476249dd94e605b6627582ad0dbcaede0159e (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.sh6
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java287
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);
}
}
}