aboutsummaryrefslogtreecommitdiffstats
path: root/src/test/com/jogamp
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2013-08-23 01:02:33 +0200
committerSven Gothel <[email protected]>2013-08-23 01:02:33 +0200
commit474ce65081ecd452215bc07ab866666cb11ca8b1 (patch)
tree8ce81c8132a4412d5d27748ddbc087094ad4c462 /src/test/com/jogamp
parent4dc4a32720e7b176e6811c0eaa8ddc060e1468da (diff)
GLMediaPlayer Multithreaded Decoding: GLMediaPlayer* (Part-5) - WIP
- Update/fix GLMediaPlayer API doc - GLMediaEventListener: Add event bits for all state changes to be delivered via attributesChanged(..) - StreamWorker / Decoder Thread: - Use StreamWorker only ! - Handle exceptions on StreamWorker via StreamException - Handles stream initialization and decoding (-> initStream(..)) - Split initGLStream(..) -> initStream(..) + initGL(GL) - allow initStream(..)'s implementation being executed on StreamWorker - allow GL initialization to be 'postponed' when stream is read, i.e. non blocking stream initialization (UI .. etc) - Handle EOS via END_OF_STREAM_PTS -> pause/event - Video: Use lock-free LFRingbuffer, similar to ALAudioSink (commit f18a94b3defef16e98badd6d99f2422609aa56c5) +++ - FFMPEGDynamicLibraryBundleInfo - Add avcodec's: - avcodec_get_frame_defaults, avcodec_free_frame (54.28.0), avcodec_flush_buffers, - Add avutil's: - av_frame_unref (55.0.0) - Add avformat's: - avformat_seek_file (??) +++ - FFMPEGMediaPlayer Native: - add 'snoop' video frames for a/v frame count relation. disabled per default, since no more needed due to ALAudioSink's grow-buffer usage of LFRingbuffer. - use sp_avcodec_free_frame if available - 'useRefCountedFrames=1' for libav 55.0 to cache more than one audio frame, not used since ALAudioSink's OpenAL usage does not require it (copies data once). Note: the above snooped-video frame count is used here. - use only one cached audio-frame (-> see above, OpenAL copies data once), while reusing the NIO buffer! - Perform OpenGL sync (glFinish) in native code! - find proper PTS value, i.e. either frame's PTS or DTS, see 'PTSStats'. - FFMPEGMediaPlayer Java: - use private fields - simplified code due to above changes. +++ Working Tests: MovieSimple and MovieCube TODO-1: Fix - Android - OMXGLMediaPlayer TODO-2: - Fix issue where async audio frames arrive much later than 1st video frame, i.e. around 300ms. - Default TextureCount .. maybe 3 ? - Adding Audio synchronization ? - Find 'truth' about correlation of audio and video PTS values, currently, we assume both to be unrelated ?
Diffstat (limited to 'src/test/com/jogamp')
-rw-r--r--src/test/com/jogamp/opengl/test/android/MovieCubeActivity0.java43
-rw-r--r--src/test/com/jogamp/opengl/test/android/MovieSimpleActivity0.java61
-rw-r--r--src/test/com/jogamp/opengl/test/android/MovieSimpleActivity1.java191
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java182
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java205
5 files changed, 436 insertions, 246 deletions
diff --git a/src/test/com/jogamp/opengl/test/android/MovieCubeActivity0.java b/src/test/com/jogamp/opengl/test/android/MovieCubeActivity0.java
index 2c434f38a..c9acab64b 100644
--- a/src/test/com/jogamp/opengl/test/android/MovieCubeActivity0.java
+++ b/src/test/com/jogamp/opengl/test/android/MovieCubeActivity0.java
@@ -48,6 +48,9 @@ import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieCube;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.util.av.GLMediaPlayer;
+import com.jogamp.opengl.util.av.GLMediaPlayer.GLMediaEventListener;
+import com.jogamp.opengl.util.av.GLMediaPlayer.StreamException;
+import com.jogamp.opengl.util.texture.TextureSequence.TextureFrame;
import android.os.Bundle;
import android.util.Log;
@@ -85,21 +88,45 @@ public class MovieCubeActivity0 extends NewtBaseActivity {
scrn.addReference();
try {
- final Animator animator = new Animator();
+ final Animator anim = new Animator();
// Main
- final MovieCube demoMain = new MovieCube(streamLoc, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, -2.3f, 0f, 0f);
final GLWindow glWindowMain = GLWindow.create(scrn, capsMain);
glWindowMain.setFullscreen(true);
setContentView(getWindow(), glWindowMain);
- glWindowMain.addMouseListener(showKeyboardMouseListener);
- glWindowMain.addGLEventListener(demoMain);
- animator.add(glWindowMain);
+ anim.add(glWindowMain);
glWindowMain.setVisible(true);
+ glWindowMain.addMouseListener(showKeyboardMouseListener);
- // animator.setUpdateFPSFrames(60, System.err);
- animator.setUpdateFPSFrames(-1, null);
- animator.resetFPSCounter();
+ final MovieCube demoMain = new MovieCube(-2.3f, 0f, 0f);
+ final GLMediaPlayer mPlayer = demoMain.getGLMediaPlayer();
+ mPlayer.addEventListener(new GLMediaEventListener() {
+ @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("Player AttributesChanges: events_mask 0x"+Integer.toHexString(event_mask)+", when "+when);
+ System.err.println("Player State: "+mp);
+ if( 0 != ( GLMediaEventListener.EVENT_CHANGE_INIT & event_mask ) ) {
+ glWindowMain.addGLEventListener(demoMain);
+ anim.setUpdateFPSFrames(60, System.err);
+ anim.resetFPSCounter();
+ }
+ if( 0 != ( ( GLMediaEventListener.EVENT_CHANGE_ERR | GLMediaEventListener.EVENT_CHANGE_EOS ) & event_mask ) ) {
+ final StreamException se = mPlayer.getStreamException();
+ if( null != se ) {
+ se.printStackTrace();
+ }
+ new Thread() {
+ public void run() {
+ glWindowMain.destroy();
+ } }.start();
+ }
+ }
+ });
+ demoMain.initStream(streamLoc, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, 0);
} catch (IOException e) {
e.printStackTrace();
}
diff --git a/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity0.java b/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity0.java
index 2c8f0eb50..d4cb226f2 100644
--- a/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity0.java
+++ b/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity0.java
@@ -27,7 +27,6 @@
*/
package com.jogamp.opengl.test.android;
-import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
@@ -49,6 +48,9 @@ import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieSimple;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.util.av.GLMediaPlayer;
+import com.jogamp.opengl.util.av.GLMediaPlayer.GLMediaEventListener;
+import com.jogamp.opengl.util.av.GLMediaPlayer.StreamException;
+import com.jogamp.opengl.util.texture.TextureSequence.TextureFrame;
import android.os.Bundle;
import android.util.Log;
@@ -84,25 +86,44 @@ public class MovieSimpleActivity0 extends NewtBaseActivity {
final com.jogamp.newt.Screen scrn = NewtFactory.createScreen(dpy, 0);
scrn.addReference();
- try {
- final Animator animator = new Animator();
-
- // Main
- final MovieSimple demoMain = new MovieSimple(streamLoc, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO);
- demoMain.setScaleOrig(true);
- final GLWindow glWindowMain = GLWindow.create(scrn, capsMain);
- glWindowMain.setFullscreen(true);
- setContentView(getWindow(), glWindowMain);
- glWindowMain.addGLEventListener(demoMain);
- animator.add(glWindowMain);
- glWindowMain.setVisible(true);
-
- animator.setUpdateFPSFrames(60, System.err);
- // animator.setUpdateFPSFrames(-1, null);
- animator.resetFPSCounter();
- } catch (IOException e) {
- e.printStackTrace();
- }
+ final Animator anim = new Animator();
+
+ // Main
+ final GLWindow glWindowMain = GLWindow.create(scrn, capsMain);
+ glWindowMain.setFullscreen(true);
+ setContentView(getWindow(), glWindowMain);
+ anim.add(glWindowMain);
+ glWindowMain.setVisible(true);
+
+ final MovieSimple demoMain = new MovieSimple();
+ demoMain.setScaleOrig(true);
+ final GLMediaPlayer mPlayer = demoMain.getGLMediaPlayer();
+ mPlayer.addEventListener( new GLMediaPlayer.GLMediaEventListener() {
+ @Override
+ public void newFrameAvailable(GLMediaPlayer ts, TextureFrame newFrame, long when) { }
+
+ @Override
+ public void attributesChanged(GLMediaPlayer mp, int event_mask, long when) {
+ System.err.println("Player AttributesChanges: events_mask 0x"+Integer.toHexString(event_mask)+", when "+when);
+ System.err.println("Player State: "+mp);
+ if( 0 != ( GLMediaEventListener.EVENT_CHANGE_INIT & event_mask ) ) {
+ glWindowMain.addGLEventListener(demoMain);
+ anim.setUpdateFPSFrames(60, System.err);
+ anim.resetFPSCounter();
+ }
+ if( 0 != ( ( GLMediaEventListener.EVENT_CHANGE_ERR | GLMediaEventListener.EVENT_CHANGE_EOS ) & event_mask ) ) {
+ final StreamException se = mPlayer.getStreamException();
+ if( null != se ) {
+ se.printStackTrace();
+ }
+ new Thread() {
+ public void run() {
+ glWindowMain.destroy();
+ } }.start();
+ }
+ }
+ });
+ demoMain.initStream(streamLoc, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, 0);
scrn.removeReference();
diff --git a/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity1.java b/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity1.java
index df6b91582..4e86883e4 100644
--- a/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity1.java
+++ b/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity1.java
@@ -27,7 +27,6 @@
*/
package com.jogamp.opengl.test.android;
-import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
@@ -51,6 +50,9 @@ import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieSimple;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.util.av.GLMediaPlayer;
+import com.jogamp.opengl.util.av.GLMediaPlayer.GLMediaEventListener;
+import com.jogamp.opengl.util.av.GLMediaPlayer.StreamException;
+import com.jogamp.opengl.util.texture.TextureSequence.TextureFrame;
import android.os.Bundle;
import android.util.Log;
@@ -110,82 +112,123 @@ public class MovieSimpleActivity1 extends NewtBaseActivity {
final com.jogamp.newt.Screen scrn = NewtFactory.createScreen(dpy, 0);
scrn.addReference();
- try {
- final Animator animator = new Animator();
-
- // Main
- final MovieSimple demoMain = new MovieSimple(streamLoc0, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO);
- if(mPlayerHUD) {
- demoMain.setEffects(MovieSimple.EFFECT_GRADIENT_BOTTOM2TOP);
- demoMain.setTransparency(0.9f);
- }
- demoMain.setScaleOrig(mPlayerNoZoom);
- final GLWindow glWindowMain = GLWindow.create(scrn, capsMain);
- {
- final int padding = mPlayerHUD ? 32 : 0;
- final android.view.View androidView = ((jogamp.newt.driver.android.WindowDriver)glWindowMain.getDelegatedWindow()).getAndroidView();
- glWindowMain.setSize(scrn.getWidth()-padding, scrn.getHeight()-padding);
- glWindowMain.setUndecorated(true);
- // setContentView(getWindow(), glWindowMain);
- viewGroup.addView(androidView, new android.widget.FrameLayout.LayoutParams(glWindowMain.getWidth(), glWindowMain.getHeight(), Gravity.BOTTOM|Gravity.RIGHT));
- registerNEWTWindow(glWindowMain);
+ final Animator anim = new Animator();
+
+ // Main
+ final GLWindow glWindowMain = GLWindow.create(scrn, capsMain);
+ {
+ final int padding = mPlayerHUD ? 32 : 0;
+ final android.view.View androidView = ((jogamp.newt.driver.android.WindowDriver)glWindowMain.getDelegatedWindow()).getAndroidView();
+ glWindowMain.setSize(scrn.getWidth()-padding, scrn.getHeight()-padding);
+ glWindowMain.setUndecorated(true);
+ // setContentView(getWindow(), glWindowMain);
+ viewGroup.addView(androidView, new android.widget.FrameLayout.LayoutParams(glWindowMain.getWidth(), glWindowMain.getHeight(), Gravity.BOTTOM|Gravity.RIGHT));
+ registerNEWTWindow(glWindowMain);
+ }
+ anim.add(glWindowMain);
+ glWindowMain.setVisible(true);
+
+ final MovieSimple demoMain = new MovieSimple();
+ final GLMediaPlayer mPlayerMain = demoMain.getGLMediaPlayer();
+ if(mPlayerHUD) {
+ demoMain.setEffects(MovieSimple.EFFECT_GRADIENT_BOTTOM2TOP);
+ demoMain.setTransparency(0.9f);
+ }
+ demoMain.setScaleOrig(mPlayerNoZoom);
+ mPlayerMain.addEventListener( new GLMediaPlayer.GLMediaEventListener() {
+ @Override
+ public void newFrameAvailable(GLMediaPlayer ts, TextureFrame newFrame, long when) { }
+
+ @Override
+ public void attributesChanged(GLMediaPlayer mp, int event_mask, long when) {
+ System.err.println("Player AttributesChanges: events_mask 0x"+Integer.toHexString(event_mask)+", when "+when);
+ System.err.println("Player State: "+mp);
+ if( 0 != ( GLMediaEventListener.EVENT_CHANGE_INIT & event_mask ) ) {
+ glWindowMain.addGLEventListener(demoMain);
+ anim.setUpdateFPSFrames(60, System.err);
+ anim.resetFPSCounter();
+ }
+ if( 0 != ( ( GLMediaEventListener.EVENT_CHANGE_ERR | GLMediaEventListener.EVENT_CHANGE_EOS ) & event_mask ) ) {
+ final StreamException se = mPlayerMain.getStreamException();
+ if( null != se ) {
+ se.printStackTrace();
+ }
+ new Thread() {
+ public void run() {
+ glWindowMain.destroy();
+ } }.start();
+ }
}
-
- glWindowMain.addGLEventListener(demoMain);
- animator.add(glWindowMain);
- glWindowMain.setVisible(true);
-
- if(mPlayerHUD) {
- final GLMediaPlayer sharedPlayer = mPlayerSharedHUD ? demoMain.getGLMediaPlayer() : null;
- final GLCapabilities capsHUD = new GLCapabilities(GLProfile.getGL2ES2());
- capsHUD.setBackgroundOpaque(false);
- final GLWindow glWindowHUD = GLWindow.create(scrn, capsHUD);
- glWindowMain.invoke(false, new GLRunnable() {
- @Override
- public boolean run(GLAutoDrawable drawable) {
- int x2 = scrn.getX();
- int y2 = scrn.getY();
- int w2 = scrn.getWidth()/3;
- int h2 = scrn.getHeight()/3;
- if(null != sharedPlayer) {
- if(0 < sharedPlayer.getWidth() && sharedPlayer.getWidth()<scrn.getWidth()/2 &&
- 0 < sharedPlayer.getHeight() && sharedPlayer.getHeight()<scrn.getHeight()/2) {
- w2 = sharedPlayer.getWidth();
- h2 = sharedPlayer.getHeight();
- }
- glWindowHUD.setSharedContext(glWindowMain.getContext());
- glWindowHUD.addGLEventListener(new MovieSimple(sharedPlayer));
- } else {
- try {
- glWindowHUD.addGLEventListener(new MovieSimple(streamLoc1, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO));
- } catch (IOException e) {
- e.printStackTrace();
+ });
+ demoMain.initStream(streamLoc0, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, 0);
+
+ if(mPlayerHUD) {
+ final GLMediaPlayer mPlayerShared = mPlayerSharedHUD ? mPlayerMain : null;
+ final GLCapabilities capsHUD = new GLCapabilities(GLProfile.getGL2ES2());
+ capsHUD.setBackgroundOpaque(false);
+ final GLWindow glWindowHUD = GLWindow.create(scrn, capsHUD);
+ glWindowMain.invoke(false, new GLRunnable() {
+ @Override
+ public boolean run(GLAutoDrawable drawable) {
+ final GLMediaPlayer mPlayerSub;
+ final MovieSimple demoHUD;
+ int x2 = scrn.getX();
+ int y2 = scrn.getY();
+ int w2 = scrn.getWidth()/3;
+ int h2 = scrn.getHeight()/3;
+ if(null != mPlayerShared) {
+ if(0 < mPlayerShared.getWidth() && mPlayerShared.getWidth()<scrn.getWidth()/2 &&
+ 0 < mPlayerShared.getHeight() && mPlayerShared.getHeight()<scrn.getHeight()/2) {
+ w2 = mPlayerShared.getWidth();
+ h2 = mPlayerShared.getHeight();
+ }
+ glWindowHUD.setSharedContext(glWindowMain.getContext());
+ demoHUD = new MovieSimple(mPlayerShared);
+ mPlayerSub = mPlayerShared;
+ } else {
+ demoHUD = new MovieSimple();
+ mPlayerSub = demoHUD.getGLMediaPlayer();
+ }
+ mPlayerSub.addEventListener( new GLMediaPlayer.GLMediaEventListener() {
+ @Override
+ public void newFrameAvailable(GLMediaPlayer ts, TextureFrame newFrame, long when) { }
+
+ @Override
+ public void attributesChanged(GLMediaPlayer mp, int event_mask, long when) {
+ if( 0 != ( GLMediaEventListener.EVENT_CHANGE_INIT & event_mask ) ) {
+ glWindowHUD.addGLEventListener(demoHUD);
+ }
+ if( 0 != ( ( GLMediaEventListener.EVENT_CHANGE_ERR | GLMediaEventListener.EVENT_CHANGE_EOS ) & event_mask ) ) {
+ final StreamException se = mPlayerMain.getStreamException();
+ if( null != se ) {
+ se.printStackTrace();
+ }
+ new Thread() {
+ public void run() {
+ glWindowHUD.destroy();
+ } }.start();
}
- }
- glWindowHUD.setPosition(x2, y2);
- glWindowHUD.setSize(w2, h2);
- System.err.println("HUD: "+mPlayerHUD);
- System.err.println("HUD: "+w2+"x"+h2);
- glWindowHUD.addMouseListener(toFrontMouseListener);
+ }
+ });
+ demoHUD.initStream(streamLoc1, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, 0);
+
+ glWindowHUD.setPosition(x2, y2);
+ glWindowHUD.setSize(w2, h2);
+ System.err.println("HUD: "+mPlayerHUD);
+ System.err.println("HUD: "+w2+"x"+h2);
+ glWindowHUD.addMouseListener(toFrontMouseListener);
- viewGroup.post(new Runnable() {
- public void run() {
- final android.view.View androidView = ((jogamp.newt.driver.android.WindowDriver)glWindowHUD.getDelegatedWindow()).getAndroidView();
- // addContentView(getWindow(), glWindowHUD, new android.view.ViewGroup.LayoutParams(glWindowHUD.getWidth(), glWindowHUD.getHeight()));
- viewGroup.addView(androidView, new android.widget.FrameLayout.LayoutParams(glWindowHUD.getWidth(), glWindowHUD.getHeight(), Gravity.TOP|Gravity.LEFT));
- registerNEWTWindow(glWindowHUD);
- animator.add(glWindowHUD);
- glWindowHUD.setVisible(true);
- } } );
- return true;
- } } );
- }
-
- animator.setUpdateFPSFrames(60, System.err);
- // animator.setUpdateFPSFrames(-1, null);
- animator.resetFPSCounter();
- } catch (IOException e) {
- e.printStackTrace();
+ viewGroup.post(new Runnable() {
+ public void run() {
+ final android.view.View androidView = ((jogamp.newt.driver.android.WindowDriver)glWindowHUD.getDelegatedWindow()).getAndroidView();
+ // addContentView(getWindow(), glWindowHUD, new android.view.ViewGroup.LayoutParams(glWindowHUD.getWidth(), glWindowHUD.getHeight()));
+ viewGroup.addView(androidView, new android.widget.FrameLayout.LayoutParams(glWindowHUD.getWidth(), glWindowHUD.getHeight(), Gravity.TOP|Gravity.LEFT));
+ registerNEWTWindow(glWindowHUD);
+ anim.add(glWindowHUD);
+ glWindowHUD.setVisible(true);
+ } } );
+ return true;
+ } } );
}
scrn.removeReference();
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java
index a9c200943..c48c53189 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java
@@ -1,34 +1,29 @@
-/*
- * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+/**
+ * Copyright 2012 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
*
- * - Redistribution of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
*
- * - Redistribution in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * Neither the name of Sun Microsystems, Inc. or the names of
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * This software is provided "AS IS," without a warranty of any kind. ALL
- * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
- * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
- * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
- * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
- * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
- * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
- * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
- * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
- * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
- * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
*/
package com.jogamp.opengl.test.junit.jogl.demos.es2.av;
@@ -58,38 +53,55 @@ import com.jogamp.opengl.test.junit.util.UITestCase;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.util.av.GLMediaPlayer;
import com.jogamp.opengl.util.av.GLMediaPlayer.GLMediaEventListener;
+import com.jogamp.opengl.util.av.GLMediaPlayer.StreamException;
import com.jogamp.opengl.util.av.GLMediaPlayerFactory;
import com.jogamp.opengl.util.texture.TextureSequence.TextureFrame;
+/**
+ * Simple cube movie player w/ aspect ration true projection on a cube.
+ */
public class MovieCube implements GLEventListener, GLMediaEventListener {
- static boolean waitForKey = false;
- int textureCount = 3; // default - threaded
- final URI streamLoc;
- final int vid, aid;
- final float zoom0, rotx, roty;
- TextureSequenceCubeES2 cube=null;
- GLMediaPlayer mPlayer=null;
+ private static boolean waitForKey = false;
+ private final float zoom0, rotx, roty;
+ private TextureSequenceCubeES2 cube=null;
+ private GLMediaPlayer mPlayer=null;
+ private int swapInterval = 1;
+ private long lastPerfPos = 0;
+ /** Blender's Big Buck Bunny Trailer: 24f 640p VP8, Vorbis 44100Hz mono, WebM/Matroska Stream. */
+ public static final URI defURI;
+ static {
+ URI _defURI = null;
+ try {
+ _defURI = new URI("http://video.webmfiles.org/big-buck-bunny_trailer.webm");
+ } catch (URISyntaxException e) {
+ e.printStackTrace();
+ }
+ defURI = _defURI;
+ }
+
public MovieCube() throws IOException, URISyntaxException {
- this(new URI("http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4"),
- GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, -2.3f, 0f, 0f);
+ this(-2.3f, 0f, 0f);
}
- public MovieCube(URI streamLoc, int vid, int aid, float zoom0, float rotx, float roty) throws IOException {
- this.streamLoc = streamLoc;
+ public MovieCube(float zoom0, float rotx, float roty) throws IOException {
this.zoom0 = zoom0;
this.rotx = rotx;
this.roty = roty;
- this.vid = vid;
- this.aid = aid;
mPlayer = GLMediaPlayerFactory.createDefault();
mPlayer.addEventListener(this);
}
- public void setTextureCount(int v) {
- textureCount = v;
+ public void initStream(URI streamLoc, int vid, int aid, int textureCount) {
+ mPlayer.addEventListener(this);
+ mPlayer.initStream(streamLoc, vid, aid, textureCount);
+ System.out.println("pC.1b "+mPlayer);
}
+ public void setSwapInterval(int v) { this.swapInterval = v; }
+
+ public GLMediaPlayer getGLMediaPlayer() { return mPlayer; }
+
private final KeyListener keyAction = new KeyAdapter() {
public void keyReleased(KeyEvent e) {
if( e.isAutoRepeat() ) {
@@ -149,7 +161,7 @@ public class MovieCube implements GLEventListener, GLMediaEventListener {
};
@Override
- public void attributesChanges(GLMediaPlayer mp, int event_mask, long when) {
+ public void attributesChanged(GLMediaPlayer mp, int event_mask, long when) {
System.out.println("attributesChanges: "+mp+", 0x"+Integer.toHexString(event_mask)+", when "+when);
}
@@ -160,6 +172,16 @@ public class MovieCube implements GLEventListener, GLMediaEventListener {
@Override
public void init(GLAutoDrawable drawable) {
+ if(null == mPlayer) {
+ throw new InternalError("mPlayer null");
+ }
+ if( GLMediaPlayer.State.Initialized != mPlayer.getState() ) {
+ throw new IllegalStateException("mPlayer not in state initialized: "+mPlayer);
+ }
+ if( GLMediaPlayer.STREAM_ID_NONE == mPlayer.getVID() ) {
+ System.err.println("MovieCube: No VID/stream selected - no GL: "+mPlayer);
+ return;
+ }
GL2ES2 gl = drawable.getGL().getGL2ES2();
System.err.println(JoglVersion.getGLInfo(gl, null));
@@ -168,19 +190,20 @@ public class MovieCube implements GLEventListener, GLMediaEventListener {
if(waitForKey) {
UITestCase.waitForKey("Init>");
}
+
try {
- mPlayer.initGLStream(gl, textureCount, streamLoc, vid, aid);
- } catch (Exception e) {
- e.printStackTrace();
+ mPlayer.initGL(gl);
+ } catch (Exception e) {
+ e.printStackTrace();
if(null != mPlayer) {
mPlayer.destroy(gl);
mPlayer = null;
}
throw new GLException(e);
}
-
cube.init(drawable);
mPlayer.play();
+ System.out.println("pStart "+mPlayer);
boolean added;
final Object upstreamWidget = drawable.getUpstreamWidget();
@@ -194,6 +217,10 @@ public class MovieCube implements GLEventListener, GLMediaEventListener {
@Override
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+ final GL2ES2 gl = drawable.getGL().getGL2ES2();
+ if(-1 != swapInterval) {
+ gl.setSwapInterval(swapInterval); // in case switching the drawable (impl. may bound attribute there)
+ }
if(null == mPlayer) { return; }
cube.reshape(drawable, x, y, width, height);
}
@@ -209,8 +236,6 @@ public class MovieCube implements GLEventListener, GLMediaEventListener {
cube=null;
}
- long lastPerfPos = 0;
-
@Override
public void display(GLAutoDrawable drawable) {
if(null == mPlayer) { return; }
@@ -225,6 +250,7 @@ public class MovieCube implements GLEventListener, GLMediaEventListener {
}
public static void main(String[] args) throws IOException, InterruptedException, URISyntaxException {
+ int swapInterval = 1;
int width = 510;
int height = 300;
int textureCount = 3; // default - threaded
@@ -237,7 +263,7 @@ public class MovieCube implements GLEventListener, GLMediaEventListener {
int aid = GLMediaPlayer.STREAM_ID_AUTO;
final boolean origSize;
- String url_s="http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4";
+ String url_s=null;
{
boolean _origSize = false;
for(int i=0; i<args.length; i++) {
@@ -269,20 +295,32 @@ public class MovieCube implements GLEventListener, GLMediaEventListener {
forceGL3 = true;
} else if(args[i].equals("-gldef")) {
forceGLDef = true;
+ } else if(args[i].equals("-vsync")) {
+ i++;
+ swapInterval = MiscUtils.atoi(args[i], swapInterval);
} else if(args[i].equals("-wait")) {
waitForKey = true;
}
}
origSize = _origSize;
}
+ final URI streamLoc;
+ if( null == url_s ) {
+ streamLoc = defURI;
+ } else {
+ streamLoc = new URI(url_s);
+ }
+ System.err.println("stream "+streamLoc);
System.err.println("vid "+vid+", aid "+aid);
System.err.println("textureCount "+textureCount);
System.err.println("forceES2 "+forceES2);
System.err.println("forceES3 "+forceES3);
System.err.println("forceGL3 "+forceGL3);
System.err.println("forceGLDef "+forceGLDef);
+ System.err.println("swapInterval "+swapInterval);
- final MovieCube mc = new MovieCube(new URI(url_s), vid, aid, -2.3f, 0f, 0f);
+ final MovieCube mc = new MovieCube(-2.3f, 0f, 0f);
+ mc.setSwapInterval(swapInterval);
final GLProfile glp;
if(forceGLDef) {
@@ -298,9 +336,15 @@ public class MovieCube implements GLEventListener, GLMediaEventListener {
}
System.err.println("GLProfile: "+glp);
final GLWindow window = GLWindow.create(new GLCapabilities(glp));
- // Size OpenGL to Video Surface
+ final Animator anim = new Animator(window);
+ window.addWindowListener(new WindowAdapter() {
+ public void windowDestroyed(WindowEvent e) {
+ anim.stop();
+ }
+ });
window.setSize(width, height);
- window.addGLEventListener(mc);
+ window.setVisible(true);
+ anim.start();
mc.mPlayer.addEventListener(new GLMediaEventListener() {
@Override
@@ -308,22 +352,30 @@ public class MovieCube implements GLEventListener, GLMediaEventListener {
}
@Override
- public void attributesChanges(final GLMediaPlayer mp, int event_mask, long when) {
+ public void attributesChanged(final GLMediaPlayer mp, int event_mask, long when) {
+ System.err.println("Player AttributesChanges: events_mask 0x"+Integer.toHexString(event_mask)+", when "+when);
+ System.err.println("Player State: "+mp);
if( 0 != ( GLMediaEventListener.EVENT_CHANGE_SIZE & event_mask ) && origSize ) {
window.setSize(mp.getWidth(), mp.getHeight());
}
+ if( 0 != ( GLMediaEventListener.EVENT_CHANGE_INIT & event_mask ) ) {
+ window.addGLEventListener(mc);
+ anim.setUpdateFPSFrames(60, System.err);
+ anim.resetFPSCounter();
+ }
+ if( 0 != ( ( GLMediaEventListener.EVENT_CHANGE_ERR | GLMediaEventListener.EVENT_CHANGE_EOS ) & event_mask ) ) {
+ final StreamException se = mc.mPlayer.getStreamException();
+ if( null != se ) {
+ se.printStackTrace();
+ }
+ new Thread() {
+ public void run() {
+ window.destroy();
+ } }.start();
+ }
}
- });
-
- final Animator anim = new Animator(window);
- window.addWindowListener(new WindowAdapter() {
- public void windowDestroyed(WindowEvent e) {
- anim.stop();
- }
- });
- window.setVisible(true);
- anim.setUpdateFPSFrames(60, System.err);
- anim.start();
+ });
+ mc.initStream(streamLoc, vid, aid, textureCount);
}
}
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 9d91ce8c8..ecf95f069 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
@@ -62,6 +62,7 @@ import com.jogamp.opengl.util.GLArrayDataServer;
import com.jogamp.opengl.util.PMVMatrix;
import com.jogamp.opengl.util.av.GLMediaPlayer;
import com.jogamp.opengl.util.av.GLMediaPlayer.GLMediaEventListener;
+import com.jogamp.opengl.util.av.GLMediaPlayer.StreamException;
import com.jogamp.opengl.util.av.GLMediaPlayerFactory;
import com.jogamp.opengl.util.glsl.ShaderCode;
import com.jogamp.opengl.util.glsl.ShaderProgram;
@@ -72,12 +73,15 @@ import com.jogamp.opengl.util.texture.TextureSequence;
import com.jogamp.opengl.util.texture.TextureSequence.TextureFrame;
/**
- *
+ * Simple planar movie player w/ orthogonal 1:1 projection.
*/
public class MovieSimple implements GLEventListener, GLMediaEventListener {
- static boolean waitForKey = false;
+ public static final int EFFECT_NORMAL = 0;
+ public static final int EFFECT_GRADIENT_BOTTOM2TOP = 1<<1;
+ public static final int EFFECT_TRANSPARENT = 1<<3;
+
+ private static boolean waitForKey = false;
private int winWidth, winHeight;
- int textureCount = 3; // default - threaded
private int prevMouseX; // , prevMouseY;
private int rotate = 0;
private boolean orthoProjection = true;
@@ -88,30 +92,32 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener {
private long startTime;
private int effects = EFFECT_NORMAL;
private float alpha = 1.0f;
-
- public static final int EFFECT_NORMAL = 0;
- public static final int EFFECT_GRADIENT_BOTTOM2TOP = 1<<1;
- public static final int EFFECT_TRANSPARENT = 1<<3;
-
- /** defaults to true */
- public void setOrthoProjection(boolean v) { orthoProjection=v; }
- public boolean getOrthoProjection() { return orthoProjection; }
+ private int swapInterval = 1;
+
+ private GLMediaPlayer mPlayer;
+ private boolean mPlayerExternal;
+ private boolean mPlayerShared;
+ private boolean mPlayerScaleOrig;
+ private GLArrayDataServer interleavedVBO;
+
+ private ShaderState st;
+ private PMVMatrix pmvMatrix;
+ private GLUniformData pmvMatrixUniform;
+ private static final String shaderBasename = "texsequence_xxx";
+ private static final String myTextureLookupName = "myTexture2D";
+
+ /** Blender's Big Buck Bunny Trailer: 24f 640p VP8, Vorbis 44100Hz mono, WebM/Matroska Stream. */
+ public static final URI defURI;
+ static {
+ URI _defURI = null;
+ try {
+ _defURI = new URI("http://video.webmfiles.org/big-buck-bunny_trailer.webm");
+ } catch (URISyntaxException e) {
+ e.printStackTrace();
+ }
+ defURI = _defURI;
+ }
- public boolean hasEffect(int e) { return 0 != ( effects & e ) ; }
- public void setEffects(int e) { effects = e; };
- public void setTransparency(float alpha) {
- this.effects |= EFFECT_TRANSPARENT;
- this.alpha = alpha;
- }
-
- GLMediaPlayer mPlayer;
- final URI stream;
- final int vid, aid;
- boolean mPlayerExternal;
- boolean mPlayerShared;
- boolean mPlayerScaleOrig;
- GLArrayDataServer interleavedVBO;
-
private final MouseListener mouseAction = new MouseAdapter() {
public void mousePressed(MouseEvent e) {
if(e.getY()<=winHeight/2 && null!=mPlayer && 1 == e.getClickCount()) {
@@ -215,16 +221,12 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener {
}
};
- public MovieSimple(URI streamLoc, int vid, int aid) throws IOException {
+ public MovieSimple() {
mPlayerScaleOrig = false;
mPlayerShared = false;
mPlayerExternal = false;
mPlayer = GLMediaPlayerFactory.createDefault();
- mPlayer.addEventListener(this);
- this.stream = streamLoc;
- this.vid = vid;
- this.aid = aid;
- System.out.println("pC.1 "+mPlayer);
+ System.out.println("pC.1a "+mPlayer);
}
public MovieSimple(GLMediaPlayer sharedMediaPlayer) throws IllegalStateException {
@@ -233,23 +235,36 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener {
mPlayerExternal = true;
mPlayer = sharedMediaPlayer;
mPlayer.addEventListener(this);
- this.stream = null;
- this.vid = sharedMediaPlayer.getVID();
- this.aid = sharedMediaPlayer.getAID();
System.out.println("pC.2 shared "+mPlayerShared+", "+mPlayer);
}
+ public void initStream(URI streamLoc, int vid, int aid, int textureCount) {
+ mPlayer.addEventListener(this);
+ mPlayer.initStream(streamLoc, vid, aid, textureCount);
+ System.out.println("pC.1b "+mPlayer);
+ }
+
+ public void setSwapInterval(int v) { this.swapInterval = v; }
+
public GLMediaPlayer getGLMediaPlayer() { return mPlayer; }
- public void setTextureCount(int v) {
- textureCount = v;
- }
public void setScaleOrig(boolean v) {
mPlayerScaleOrig = v;
}
+ /** defaults to true */
+ public void setOrthoProjection(boolean v) { orthoProjection=v; }
+ public boolean getOrthoProjection() { return orthoProjection; }
+
+ public boolean hasEffect(int e) { return 0 != ( effects & e ) ; }
+ public void setEffects(int e) { effects = e; };
+ public void setTransparency(float alpha) {
+ this.effects |= EFFECT_TRANSPARENT;
+ this.alpha = alpha;
+ }
+
@Override
- public void attributesChanges(GLMediaPlayer mp, int event_mask, long when) {
+ public void attributesChanged(GLMediaPlayer mp, int event_mask, long when) {
System.out.println("attributesChanges: "+mp+", 0x"+Integer.toHexString(event_mask)+", when "+when);
}
@@ -258,19 +273,6 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener {
// System.out.println("newFrameAvailable: "+mp+", when "+when);
}
- public void play() {
- if(null!=mPlayer) {
- mPlayer.play();
- System.out.println("pStart "+mPlayer);
- }
- }
-
- ShaderState st;
- PMVMatrix pmvMatrix;
- GLUniformData pmvMatrixUniform;
- static final String shaderBasename = "texsequence_xxx";
- static final String myTextureLookupName = "myTexture2D";
-
private void initShader(GL2ES2 gl) {
// Create & Compile the shader objects
ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, MovieSimple.class,
@@ -307,6 +309,16 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener {
@Override
public void init(GLAutoDrawable drawable) {
+ if(null == mPlayer) {
+ throw new InternalError("mPlayer null");
+ }
+ if( GLMediaPlayer.State.Initialized != mPlayer.getState() ) {
+ throw new IllegalStateException("mPlayer not in state initialized: "+mPlayer);
+ }
+ if( GLMediaPlayer.STREAM_ID_NONE == mPlayer.getVID() ) {
+ System.err.println("MovieSimple: No VID/stream selected - no GL: "+mPlayer);
+ return;
+ }
zoom0 = orthoProjection ? 0f : -2.5f;
zoom1 = orthoProjection ? 0f : -5f;
zoom = zoom0;
@@ -324,7 +336,7 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener {
try {
System.out.println("p0 "+mPlayer+", shared "+mPlayerShared);
if(!mPlayerShared) {
- mPlayer.initGLStream(gl, textureCount, stream, vid, aid);
+ mPlayer.initGL(gl);
}
tex = mPlayer.getLastTexture().getTexture();
System.out.println("p1 "+mPlayer+", shared "+mPlayerShared);
@@ -405,9 +417,9 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener {
final FloatBuffer ib = (FloatBuffer)interleavedVBO.getBuffer();
final TextureCoords tc = tex.getImageTexCoords();
final float aspect = tex.getAspectRatio();
+ System.err.println("XXX0: "+tc);
System.err.println("XXX0: tex aspect: "+aspect);
System.err.println("XXX0: tex y-flip: "+tex.getMustFlipVertically());
- System.err.println("XXX0: "+tex.getImageTexCoords());
// left-bottom
ib.put(verts[0]); ib.put(verts[1]); ib.put(verts[2]);
@@ -458,11 +470,10 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener {
System.out.println("iVBO: "+interleavedVBO);
System.out.println(st);
- if(null!=mPlayer) {
- play();
- System.out.println("p2 "+mPlayer);
- }
-
+ if(!mPlayerShared) {
+ mPlayer.play();
+ System.out.println("pStart "+mPlayer);
+ }
startTime = System.currentTimeMillis();
final Object upstreamWidget = drawable.getUpstreamWidget();
@@ -477,13 +488,19 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener {
@Override
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+ final GL2ES2 gl = drawable.getGL().getGL2ES2();
+ if(-1 != swapInterval) {
+ gl.setSwapInterval(swapInterval); // in case switching the drawable (impl. may bound attribute there)
+ }
if(null == mPlayer) { return; }
+ if( GLMediaPlayer.STREAM_ID_NONE == mPlayer.getVID() ) {
+ return;
+ }
winWidth = width;
winHeight = height;
if(null != st) {
reshapePMV(width, height);
- GL2ES2 gl = drawable.getGL().getGL2ES2();
st.useProgram(gl, true);
st.uniform(gl, pmvMatrixUniform);
st.useProgram(gl, false);
@@ -548,6 +565,10 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener {
lastPerfPos = currentPos;
}
+ if( GLMediaPlayer.STREAM_ID_NONE == mPlayer.getVID() ) {
+ return;
+ }
+
GL2ES2 gl = drawable.getGL().getGL2ES2();
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
@@ -575,7 +596,7 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener {
if(mPlayerShared) {
texFrame=mPlayer.getLastTexture();
} else {
- texFrame=mPlayer.getNextTexture(gl, true);
+ texFrame=mPlayer.getNextTexture(gl);
}
if(null != texFrame) {
tex = texFrame.getTexture();
@@ -593,6 +614,7 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener {
}
public static void main(String[] args) throws IOException, URISyntaxException {
+ int swapInterval = 1;
int width = 640;
int height = 600;
int textureCount = 3; // default - threaded
@@ -607,7 +629,7 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener {
int aid = GLMediaPlayer.STREAM_ID_AUTO;
final boolean origSize;
- String url_s="http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4";
+ String url_s=null;
{
boolean _origSize = false;
for(int i=0; i<args.length; i++) {
@@ -636,6 +658,9 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener {
forceGL3 = true;
} else if(args[i].equals("-gldef")) {
forceGLDef = true;
+ } else if(args[i].equals("-vsync")) {
+ i++;
+ swapInterval = MiscUtils.atoi(args[i], swapInterval);
} else if(args[i].equals("-projection")) {
ortho=false;
} else if(args[i].equals("-zoom")) {
@@ -649,16 +674,23 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener {
}
origSize = _origSize;
}
+ final URI streamLoc;
+ if( null == url_s ) {
+ streamLoc = defURI;
+ } else {
+ streamLoc = new URI(url_s);
+ }
+ System.err.println("stream "+streamLoc);
System.err.println("vid "+vid+", aid "+aid);
System.err.println("textureCount "+textureCount);
System.err.println("forceES2 "+forceES2);
System.err.println("forceES3 "+forceES3);
System.err.println("forceGL3 "+forceGL3);
System.err.println("forceGLDef "+forceGLDef);
+ System.err.println("swapInterval "+swapInterval);
- final URI streamURI = new URI(url_s);
- final MovieSimple ms = new MovieSimple(streamURI, vid, aid);
- ms.setTextureCount(textureCount);
+ final MovieSimple ms = new MovieSimple();
+ ms.setSwapInterval(swapInterval);
ms.setScaleOrig(!zoom);
ms.setOrthoProjection(ortho);
@@ -678,31 +710,46 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener {
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() {
+ public void windowDestroyed(WindowEvent e) {
+ anim.stop();
+ }
+ });
+ window.setSize(width, height);
+ window.setVisible(true);
+ anim.start();
- window.addGLEventListener(ms);
ms.mPlayer.addEventListener(new GLMediaEventListener() {
@Override
public void newFrameAvailable(GLMediaPlayer ts, TextureFrame newFrame, long when) {
}
@Override
- public void attributesChanges(final GLMediaPlayer mp, int event_mask, long when) {
+ public void attributesChanged(final GLMediaPlayer mp, int event_mask, long when) {
+ System.err.println("Player AttributesChanges: events_mask 0x"+Integer.toHexString(event_mask)+", when "+when);
+ System.err.println("Player State: "+mp);
if( 0 != ( GLMediaEventListener.EVENT_CHANGE_SIZE & event_mask ) && origSize ) {
window.setSize(mp.getWidth(), mp.getHeight());
}
- }
- });
-
- window.setSize(width, height);
- window.setVisible(true);
- final Animator anim = new Animator(window);
- anim.setUpdateFPSFrames(60, System.err);
- anim.start();
- window.addWindowListener(new WindowAdapter() {
- public void windowDestroyed(WindowEvent e) {
- anim.stop();
- }
+ if( 0 != ( GLMediaEventListener.EVENT_CHANGE_INIT & event_mask ) ) {
+ window.addGLEventListener(ms);
+ anim.setUpdateFPSFrames(60, System.err);
+ anim.resetFPSCounter();
+ }
+ if( 0 != ( ( GLMediaEventListener.EVENT_CHANGE_ERR | GLMediaEventListener.EVENT_CHANGE_EOS ) & event_mask ) ) {
+ final StreamException se = ms.mPlayer.getStreamException();
+ if( null != se ) {
+ se.printStackTrace();
+ }
+ new Thread() {
+ public void run() {
+ window.destroy();
+ } }.start();
+ }
+ }
});
+ ms.initStream(streamLoc, vid, aid, textureCount);
} catch (Throwable t) {
t.printStackTrace();
}