diff options
author | Sven Gothel <[email protected]> | 2013-11-01 12:38:54 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2013-11-01 12:38:54 +0100 |
commit | f4574bf6846f2084f6a403552f7be6e845107c73 (patch) | |
tree | 1699c8bee62797231657265a741acad58d1a43e9 /src | |
parent | 33db4580da46ba21771499fdf50489e60294e439 (diff) |
Bug 885 - GLMediaPlayer: Allow single threaded mode - Especially where multiple media textures (Android) or shared GL context are not usable.
- GLMediaPlayer:
- TEXTURE_COUNT_MIN is the new minimum: '1' - i.e. no multithreading, single threaded player
- TEXTURE_COUNT_DEFAULT is '4' - multithreaded
- GLMediaPlayerImpl:
- Add Single threaded mode, but perform initStreamImpl(..) off-thread.
-
Diffstat (limited to 'src')
5 files changed, 189 insertions, 108 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java b/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java index 3f6b78d7e..f0864f949 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java +++ b/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java @@ -186,8 +186,11 @@ public interface GLMediaPlayer extends TextureSequence { public static final boolean DEBUG = Debug.debug("GLMediaPlayer"); public static final boolean DEBUG_NATIVE = Debug.debug("GLMediaPlayer.Native"); - /** Minimum texture count, value {@value}. */ - public static final int TEXTURE_COUNT_MIN = 4; + /** Default texture count, value {@value}. */ + public static final int TEXTURE_COUNT_DEFAULT = 4; + + /** Minimum texture count, value {@value}. Using the minimum texture count disables multi-threaded decoding. */ + public static final int TEXTURE_COUNT_MIN = 1; /** Constant {@value} for <i>mute</i> or <i>not available</i>. See <a href="#streamIDs">Audio and video Stream IDs</a>. */ public static final int STREAM_ID_NONE = -2; @@ -350,7 +353,7 @@ public interface GLMediaPlayer extends TextureSequence { * @param vid video stream id, see <a href="#streamIDs">audio and video Stream IDs</a> * @param aid video stream id, see <a href="#streamIDs">audio and video Stream IDs</a> * @param textureCount desired number of buffered textures to be decoded off-thread, will be validated by implementation. - * The minimum value is {@link #TEXTURE_COUNT_MIN}. + * The minimum value is {@link #TEXTURE_COUNT_DEFAULT}. * Ignored if video is muted. * @throws IllegalStateException if not invoked in {@link State#Uninitialized} * @throws IllegalArgumentException if arguments are invalid diff --git a/src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java b/src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java index 415ee65a2..25a0bc15d 100644 --- a/src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java +++ b/src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java @@ -56,6 +56,11 @@ import android.view.Surface; * Android implementation utilizes API level 14 (4.0.? ICS) features * as listed below. * <p> + * Implementation is single threaded only, since we are not able to utilize multiple textures. + * We would need to add an implementation for API level 16 using MediaCodec/MediaExtractor + * to expose multithreading on multiple surface/textures. + * </p> + * <p> * We utilize the {@link MediaPlayer} with direct to texture streaming. * The MediaPlayer uses <code>libstagefright</code> to access the OpenMAX AL implementation * for hardware decoding. @@ -248,8 +253,7 @@ public class AndroidGLMediaPlayerAPI14 extends GLMediaPlayerImpl { } @Override - protected final void initStreamImpl(int vid, int aid) throws IOException { - + protected final void initStreamImpl(final int vid, final int aid) throws IOException { if( null == streamLoc ) { return; } @@ -297,6 +301,21 @@ public class AndroidGLMediaPlayerAPI14 extends GLMediaPlayerImpl { mp.getVideoWidth(), mp.getVideoHeight(), 0, 0, 0, 0f, 0, 0, mp.getDuration(), icodec, icodec); + /** + mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { + @Override + public void onPrepared(final MediaPlayer mp) { + final int r_aid = GLMediaPlayer.STREAM_ID_NONE == aid ? GLMediaPlayer.STREAM_ID_NONE : 1; // fake + final String icodec = "android"; + updateAttributes(0, r_aid, // fake + mp.getVideoWidth(), mp.getVideoHeight(), 0, + 0, 0, 0f, + 0, 0, mp.getDuration(), icodec, icodec); + } + }); + mp.prepareAsync(); + * + */ } else if( null != cam ) { final String icodec = "android"; final int[] fpsRange = { 0, 0 }; @@ -336,23 +355,20 @@ public class AndroidGLMediaPlayerAPI14 extends GLMediaPlayerImpl { /** * {@inheritDoc} * <p> - * Returns 2 - implementation duplicates single texture + * Returns {@link #TEXTURE_COUNT_MIN}, using a single texture * </p> */ @Override protected int validateTextureCount(int desiredTextureCount) { - return 2; + return TEXTURE_COUNT_MIN; } @Override protected final int getNextTextureImpl(GL gl, TextureFrame nextFrame) { int pts = TimeFrameI.INVALID_PTS; if(null != mp || null != cam) { - final SurfaceTextureFrame sTexFrame = (SurfaceTextureFrame) nextFrame; + final SurfaceTextureFrame sTexFrame = null != nextFrame ? (SurfaceTextureFrame) nextFrame : singleSTexFrame; final SurfaceTexture surfTex = sTexFrame.surfaceTex; - if( sTexFrame != singleSTexFrame ) { - throw new InternalError("XXX: sTexFrame: "+sTexFrame+", singleSTexFrame "+singleSTexFrame); - } if( !sTexFrameAttached ) { sTexFrameAttached = true; final Surface surface; diff --git a/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java b/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java index 1d73d1a44..91647394d 100644 --- a/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java +++ b/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java @@ -304,7 +304,9 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { if( null != audioSink ) { audioSink.play(); // cont. w/ new data } - streamWorker.doResume(); + if( null != streamWorker ) { + streamWorker.doResume(); + } changeState(0, State.Playing); } default: @@ -325,7 +327,9 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { if( State.Playing == state ) { event_mask = addStateEventMask(event_mask, GLMediaPlayer.State.Paused); state = State.Paused; - streamWorker.doPause(); + if( null != streamWorker ) { + streamWorker.doPause(); + } if( flush ) { resetAVPTSAndFlush(); } else if( null != audioSink ) { @@ -348,8 +352,10 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { } private final State destroyImpl(GL gl, int event_mask) { synchronized( stateLock ) { - streamWorker.doStop(); - streamWorker = null; + if( null != streamWorker ) { + streamWorker.doStop(); + streamWorker = null; + } destroyImpl(gl); removeAllTextureFrames(gl); textureCount=0; @@ -369,14 +375,18 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { case Paused: final State _state = state; state = State.Paused; - streamWorker.doPause(); + if( null != streamWorker ) { + streamWorker.doPause(); + } pts1 = seekImpl(msec); resetAVPTSAndFlush(); if( null != audioSink && State.Playing == _state ) { audioSink.play(); // cont. w/ new data } System.err.println("SEEK XXX: "+getPerfString()); - streamWorker.doResume(); + if( null != streamWorker ) { + streamWorker.doResume(); + } state = _state; break; default: @@ -476,7 +486,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { } @Override - public final void initStream(URI streamLoc, int vid, int aid, int reqTextureCount) throws IllegalStateException, IllegalArgumentException { + public final void initStream(URI streamLoc, final int vid, final int aid, int reqTextureCount) throws IllegalStateException, IllegalArgumentException { synchronized( stateLock ) { if(State.Uninitialized != state) { throw new IllegalStateException("Instance not in state unintialized: "+this); @@ -486,8 +496,8 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { } if( STREAM_ID_NONE != vid ) { textureCount = validateTextureCount(reqTextureCount); - if( textureCount < 2 ) { - throw new InternalError("Validated texture count < 2: "+textureCount); + if( textureCount < TEXTURE_COUNT_MIN ) { + throw new InternalError("Validated texture count < "+TEXTURE_COUNT_MIN+": "+textureCount); } } else { textureCount = 0; @@ -515,8 +525,21 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { this.vid = vid; this.aid = aid; - if (this.streamLoc != null) { - streamWorker = new StreamWorker(); + if ( this.streamLoc != null ) { + if( TEXTURE_COUNT_MIN < textureCount ) { + streamWorker = new StreamWorker(); + } else { + new Thread() { + public void run() { + try { + initStreamImpl(vid, aid); + } catch (Throwable t) { + streamErr = new StreamException(t.getClass().getSimpleName()+" while initializing: "+GLMediaPlayerImpl.this.toString(), t); + changeState(GLMediaEventListener.EVENT_CHANGE_ERR, GLMediaPlayer.State.Uninitialized); + } // also initializes width, height, .. etc + } + }.start(); + } } } } @@ -537,13 +560,12 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { @Override public final StreamException getStreamException() { + final StreamException e; synchronized( stateLock ) { - if( null != streamWorker ) { - return streamWorker.getStreamErr(); - } else { - return null; - } + e = streamErr; + streamErr = null; } + return e; } @Override @@ -552,11 +574,13 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { if(State.Initialized != state ) { throw new IllegalStateException("Stream not in state initialized: "+this); } - final StreamException streamInitErr = streamWorker.getStreamErr(); - if( null != streamInitErr ) { - streamWorker = null; // already terminated! - destroy(null); - throw streamInitErr; + if( null != streamWorker ) { + final StreamException streamInitErr = getStreamException(); + if( null != streamInitErr ) { + streamWorker = null; // already terminated! + destroy(null); + throw streamInitErr; + } } try { if( STREAM_ID_NONE != vid ) { @@ -566,10 +590,18 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { System.err.println("initGLImpl.X "+this); } videoFramesOrig = createTexFrames(gl, textureCount); - videoFramesFree = new LFRingbuffer<TextureFrame>(videoFramesOrig); - videoFramesDecoded = new LFRingbuffer<TextureFrame>(TextureFrame[].class, textureCount); - lastFrame = videoFramesFree.getBlocking( ); - streamWorker.initGL(gl); + if( TEXTURE_COUNT_MIN == textureCount ) { + videoFramesFree = null; + videoFramesDecoded = null; + lastFrame = videoFramesOrig[0]; + } else { + videoFramesFree = new LFRingbuffer<TextureFrame>(videoFramesOrig); + videoFramesDecoded = new LFRingbuffer<TextureFrame>(TextureFrame[].class, textureCount); + lastFrame = videoFramesFree.getBlocking( ); + } + if( null != streamWorker ) { + streamWorker.initGL(gl); + } } else { removeAllTextureFrames(null); initGLImpl(null); @@ -601,10 +633,11 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { /** * Returns the validated number of textures to be handled. * <p> - * Default is {@link #TEXTURE_COUNT_MIN} minimum textures. + * Default is {@link #TEXTURE_COUNT_DEFAULT} minimum textures, if <code>desiredTextureCount</code> + * is < {@link #TEXTURE_COUNT_MIN}, {@link #TEXTURE_COUNT_MIN} is returned. * </p> * <p> - * Implementation must at least return a texture count of <i>two</i>, the last texture and the decoding texture. + * Implementation must at least return a texture count of {@link #TEXTURE_COUNT_MIN}, <i>two</i>, the last texture and the decoding texture. * </p> */ protected int validateTextureCount(int desiredTextureCount) { @@ -737,7 +770,11 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { cachedFrame = null; presentedFrameCount--; } else if( STREAM_ID_NONE != vid ) { - nextFrame = videoFramesDecoded.get(); + if( null != videoFramesDecoded ) { // single threaded ? TEXTURE_COUNT_MIN == textureCount + nextFrame = videoFramesDecoded.get(); + } else { + nextFrame = getNextSingleThreaded(gl, lastFrame); + } } currentTimeMillis = Platform.currentTimeMillis(); if( null != nextFrame ) { @@ -785,7 +822,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { if( dt > maxVideoDelay ) { cachedFrame = nextFrame; nextFrame = null; - } else if ( !droppedFrame && dt < -maxVideoDelay && videoFramesDecoded.size() > 0 ) { + } else if ( !droppedFrame && dt < -maxVideoDelay && null != videoFramesDecoded && videoFramesDecoded.size() > 0 ) { // only drop if prev. frame has not been dropped and // frame is too late and one decoded frame is already available. dropFrame = true; @@ -802,7 +839,8 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { } else if( DEBUG ) { System.err.println("Invalid PTS: "+nextFrame); } - if( null != nextFrame ) { + if( null != nextFrame && null != videoFramesFree ) { + // Had frame and not single threaded ? (TEXTURE_COUNT_MIN < textureCount) final TextureFrame _lastFrame = lastFrame; lastFrame = nextFrame; videoFramesFree.putBlocking(_lastFrame); @@ -857,6 +895,27 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { */ protected abstract int getNextTextureImpl(GL gl, TextureFrame nextFrame); + protected final TextureFrame getNextSingleThreaded(final GL gl, final TextureFrame nextFrame) throws InterruptedException { + if( STREAM_ID_NONE != vid ) { + preNextTextureImpl(gl); + final int vPTS = getNextTextureImpl(gl, nextFrame); + postNextTextureImpl(gl); + if( TimeFrameI.INVALID_PTS != vPTS ) { + newFrameAvailable(nextFrame, Platform.currentTimeMillis()); + return nextFrame; + } + } else { + // audio only + final int vPTS = getNextTextureImpl(null, null); + if( TimeFrameI.INVALID_PTS != vPTS && TimeFrameI.END_OF_STREAM_PTS == vPTS ) { + // state transition incl. notification + pauseImpl(true, GLMediaEventListener.EVENT_CHANGE_EOS); + } + } + return null; + } + + /** * {@inheritDoc} * <p> @@ -887,8 +946,6 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { videoFramesFree.resetFull(videoFramesOrig); lastFrame = videoFramesFree.get(); if( null == lastFrame ) { throw new InternalError("XXX"); } - } - if( null != videoFramesDecoded ) { videoFramesDecoded.clear(); } cachedFrame = null; @@ -933,7 +990,6 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { private volatile boolean shallPause = true; private volatile boolean shallStop = false; - private volatile StreamException streamErr = null; private volatile GLContext sharedGLCtx = null; private boolean sharedGLCtxCurrent = false; private GLDrawable dummyDrawable = null; @@ -977,7 +1033,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { } } - public synchronized void initGL(GL gl) { + public final synchronized void initGL(GL gl) { final GLContext glCtx = gl.getContext(); final boolean glCtxCurrent = glCtx.isCurrent(); final GLProfile glp = gl.getGLProfile(); @@ -993,7 +1049,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { sharedGLCtx.release(); } } - public synchronized void doPause() { + public final synchronized void doPause() { if( isActive ) { shallPause = true; if( Thread.currentThread() != this ) { @@ -1010,7 +1066,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { } } } - public synchronized void doResume() { + public final synchronized void doResume() { if( isRunning && !isActive ) { shallPause = false; if( Thread.currentThread() != this ) { @@ -1025,7 +1081,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { } } } - public synchronized void doStop() { + public final synchronized void doStop() { if( isRunning ) { shallStop = true; if( Thread.currentThread() != this ) { @@ -1043,12 +1099,11 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { } } } - public boolean isRunning() { return isRunning; } - public boolean isActive() { return isActive; } - public StreamException getStreamErr() { return streamErr; } + public final boolean isRunning() { return isRunning; } + public final boolean isActive() { return isActive; } @Override - public void run() { + public final void run() { setName(getName()+"-StreamWorker_"+StreamWorkerInstanceId); StreamWorkerInstanceId++; @@ -1109,9 +1164,9 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { if( !shallStop ) { TextureFrame nextFrame = null; try { - final GL gl; isBlocked = true; - if( null != videoFramesFree ) { + final GL gl; + if( STREAM_ID_NONE != vid ) { nextFrame = videoFramesFree.getBlocking(); nextFrame.setPTS( TimeFrameI.INVALID_PTS ); // mark invalid until processed! gl = sharedGLCtx.getGL(); @@ -1178,6 +1233,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { } static int StreamWorkerInstanceId = 0; private StreamWorker streamWorker = null; + private volatile StreamException streamErr = null; protected final int addStateEventMask(int event_mask, State newState) { if( state != newState ) { @@ -1396,8 +1452,14 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { } else { audioSinkInfo = ""; } - final int freeVideoFrames = null != videoFramesFree ? videoFramesFree.size() : 0; - final int decVideoFrames = null != videoFramesDecoded ? videoFramesDecoded.size() : 0; + final int freeVideoFrames, decVideoFrames; + if( null != videoFramesFree ) { + freeVideoFrames = videoFramesFree.size(); + decVideoFrames = videoFramesDecoded.size(); + } else { + freeVideoFrames = 0; + decVideoFrames = 0; + } return state+", frames[(p "+presentedFrameCount+", d "+decodedFrameCount+") / "+videoFrames+", "+tt+" s], "+ "speed " + playSpeed+", dAV "+( d_vpts - d_apts )+", vSCR "+video_scr+", vpts "+video_pts+", dSCR["+d_vpts+", avrg "+video_dpts_avg_diff+"], "+ "aSCR "+audio_scr+", apts "+audio_pts+" ( "+d_apts+" ), "+audioSinkInfo+ diff --git a/src/jogl/classes/jogamp/opengl/util/av/NullGLMediaPlayer.java b/src/jogl/classes/jogamp/opengl/util/av/NullGLMediaPlayer.java index 840149272..fc621a1dd 100644 --- a/src/jogl/classes/jogamp/opengl/util/av/NullGLMediaPlayer.java +++ b/src/jogl/classes/jogamp/opengl/util/av/NullGLMediaPlayer.java @@ -150,12 +150,12 @@ public class NullGLMediaPlayer extends GLMediaPlayerImpl { /** * {@inheritDoc} * <p> - * Returns 2 + * Returns {@link GLMediaPlayer#TEXTURE_COUNT_MIN}. * </p> */ @Override protected int validateTextureCount(int desiredTextureCount) { - return 2; + return TEXTURE_COUNT_MIN; } @Override 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 fe11f6aca..a7636fce4 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 @@ -3,14 +3,14 @@ * * 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. - * + * * 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. - * + * * 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 @@ -20,7 +20,7 @@ * 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. @@ -58,7 +58,7 @@ 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. + * Simple cube movie player w/ aspect ration true projection on a cube. */ public class MovieCube implements GLEventListener { private static boolean waitForKey = false; @@ -68,7 +68,7 @@ public class MovieCube implements GLEventListener { private int swapInterval = 1; private long lastPerfPos = 0; private volatile boolean resetGLState = false; - + /** Blender's Big Buck Bunny Trailer: 24f 640p VP8, Vorbis 44100Hz mono, WebM/Matroska Stream. */ public static final URI defURI; static { @@ -80,18 +80,18 @@ public class MovieCube implements GLEventListener { } defURI = _defURI; } - - /** - * Default constructor which also issues {@link #initStream(URI, int, int, int)} w/ default values + + /** + * Default constructor which also issues {@link #initStream(URI, int, int, int)} w/ default values * and polls until the {@link GLMediaPlayer} is {@link GLMediaPlayer.State#Initialized}. * If {@link GLMediaEventListener#EVENT_CHANGE_EOS} is reached, the stream is started over again. * <p> * This default constructor is merely useful for some <i>drop-in</i> test, e.g. using an applet. - * </p> + * </p> */ public MovieCube() throws IOException, URISyntaxException { this(-2.3f, 0f, 0f); - + mPlayer.addEventListener(new GLMediaEventListener() { @Override public void newFrameAvailable(GLMediaPlayer ts, TextureFrame newFrame, long when) { } @@ -108,9 +108,9 @@ public class MovieCube implements GLEventListener { mPlayer.seek(0); mPlayer.play(); } - } + } }); - initStream(defURI, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, 3 /* textureCount */); + initStream(defURI, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.TEXTURE_COUNT_DEFAULT); StreamException se = null; while( null == se && GLMediaPlayer.State.Initialized != mPlayer.getState() ) { try { @@ -123,7 +123,7 @@ public class MovieCube implements GLEventListener { throw new RuntimeException(se); } } - + /** Custom constructor, user needs to issue {@link #initStream(URI, int, int, int)} afterwards. */ public MovieCube(float zoom0, float rotx, float roty) throws IOException { this.zoom0 = zoom0; @@ -136,20 +136,20 @@ public class MovieCube implements GLEventListener { 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 resetGLState() { resetGLState = true; } - + private final KeyListener keyAction = new KeyAdapter() { public void keyReleased(KeyEvent e) { if( e.isAutoRepeat() ) { return; - } + } System.err.println("MC "+e); int pts0 = mPlayer.getVideoPTS(); int pts1 = 0; @@ -175,7 +175,7 @@ public class MovieCube implements GLEventListener { break; } case KeyEvent.VK_MULTIPLY: - mPlayer.setPlaySpeed(1.0f); + mPlayer.setPlaySpeed(1.0f); break; case KeyEvent.VK_SUBTRACT: { float playSpeed = mPlayer.getPlaySpeed(); @@ -184,7 +184,7 @@ public class MovieCube implements GLEventListener { } else { playSpeed -= 0.1f; } - mPlayer.setPlaySpeed(playSpeed); + mPlayer.setPlaySpeed(playSpeed); } break; case KeyEvent.VK_ADD: { float playSpeed = mPlayer.getPlaySpeed(); @@ -193,7 +193,7 @@ public class MovieCube implements GLEventListener { } else { playSpeed += 0.1f; } - mPlayer.setPlaySpeed(playSpeed); + mPlayer.setPlaySpeed(playSpeed); } break; case KeyEvent.VK_M: { float audioVolume = mPlayer.getAudioVolume(); @@ -202,16 +202,16 @@ public class MovieCube implements GLEventListener { } else { audioVolume = 1f; } - mPlayer.setAudioVolume(audioVolume); + mPlayer.setAudioVolume(audioVolume); } break; } - + if( 0 != pts1 ) { mPlayer.seek(pts1); } - } + } }; - + @Override public void init(GLAutoDrawable drawable) { if(null == mPlayer) { @@ -224,16 +224,16 @@ public class MovieCube implements GLEventListener { // throw new IllegalStateException("mPlayer has no VID/stream selected: "+mPlayer); } resetGLState = false; - + GL2ES2 gl = drawable.getGL().getGL2ES2(); System.err.println(JoglVersion.getGLInfo(gl, null)); - cube = new TextureSequenceCubeES2(mPlayer, false, zoom0, rotx, roty); - + cube = new TextureSequenceCubeES2(mPlayer, false, zoom0, rotx, roty); + if(waitForKey) { UITestCase.waitForKey("Init>"); } - + if( GLMediaPlayer.State.Initialized == mPlayer.getState() ) { try { mPlayer.initGL(gl); @@ -252,11 +252,11 @@ public class MovieCube implements GLEventListener { boolean added; final Object upstreamWidget = drawable.getUpstreamWidget(); - if (upstreamWidget instanceof Window) { + if (upstreamWidget instanceof Window) { final Window window = (Window) upstreamWidget; window.addKeyListener(keyAction); added = true; - } else { added = false; } + } else { added = false; } System.err.println("MC.init: kl-added "+added+", "+drawable.getClass().getName()); } @@ -275,11 +275,11 @@ public class MovieCube implements GLEventListener { System.err.println(Thread.currentThread()+" MovieCube.dispose ... "); disposeImpl(drawable, true); } - + private void disposeImpl(GLAutoDrawable drawable, boolean disposePlayer) { if(null == mPlayer) { return; } final Object upstreamWidget = drawable.getUpstreamWidget(); - if (upstreamWidget instanceof Window) { + if (upstreamWidget instanceof Window) { final Window window = (Window) upstreamWidget; window.removeKeyListener(keyAction); } @@ -289,14 +289,14 @@ public class MovieCube implements GLEventListener { mPlayer=null; } cube.dispose(drawable); - cube=null; + cube=null; } - + @Override public void display(GLAutoDrawable drawable) { if(null == mPlayer) { return; } - + if( resetGLState ) { resetGLState = false; System.err.println("XXX resetGLState"); @@ -304,11 +304,11 @@ public class MovieCube implements GLEventListener { init(drawable); reshape(drawable, 0, 0, drawable.getWidth(), drawable.getHeight()); } - + final long currentPos = System.currentTimeMillis(); if( currentPos - lastPerfPos > 2000 ) { System.err.println( mPlayer.getPerfString() ); - lastPerfPos = currentPos; + lastPerfPos = currentPos; } cube.display(drawable); } @@ -317,7 +317,7 @@ public class MovieCube implements GLEventListener { int swapInterval = 1; int width = 510; int height = 300; - int textureCount = 3; // default - threaded + int textureCount = GLMediaPlayer.TEXTURE_COUNT_DEFAULT; // default - threaded boolean forceES2 = false; boolean forceES3 = false; @@ -326,10 +326,10 @@ public class MovieCube implements GLEventListener { int vid = GLMediaPlayer.STREAM_ID_AUTO; int aid = GLMediaPlayer.STREAM_ID_AUTO; final boolean origSize; - + String url_s=null; { - boolean _origSize = false; + boolean _origSize = false; for(int i=0; i<args.length; i++) { if(args[i].equals("-vid")) { i++; @@ -382,10 +382,10 @@ public class MovieCube implements GLEventListener { System.err.println("forceGL3 "+forceGL3); System.err.println("forceGLDef "+forceGLDef); System.err.println("swapInterval "+swapInterval); - + final MovieCube mc = new MovieCube(-2.3f, 0f, 0f); mc.setSwapInterval(swapInterval); - + final GLProfile glp; if(forceGLDef) { glp = GLProfile.getDefault(); @@ -397,19 +397,19 @@ public class MovieCube implements GLEventListener { glp = GLProfile.get(GLProfile.GLES2); } else { glp = GLProfile.getGL2ES2(); - } + } System.err.println("GLProfile: "+glp); final GLWindow window = GLWindow.create(new GLCapabilities(glp)); 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(); - + mc.mPlayer.addEventListener(new GLMediaEventListener() { @Override public void newFrameAvailable(GLMediaPlayer ts, TextureFrame newFrame, long when) { @@ -434,15 +434,15 @@ public class MovieCube implements GLEventListener { if( 0 != ( ( GLMediaEventListener.EVENT_CHANGE_ERR | GLMediaEventListener.EVENT_CHANGE_EOS ) & event_mask ) ) { final StreamException se = mc.mPlayer.getStreamException(); if( null != se ) { - se.printStackTrace(); + se.printStackTrace(); } new Thread() { public void run() { window.destroy(); } }.start(); } - } - }); + } + }); mc.initStream(streamLoc, vid, aid, textureCount); } } |