diff options
4 files changed, 38 insertions, 20 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 5072c410d..63fc693ca 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java +++ b/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java @@ -85,7 +85,7 @@ import com.jogamp.opengl.util.TimeFrameI; * <tr><td>{@link #initStream(URI, int, int, int)}</td> <td>{@link State#Uninitialized Uninitialized}</td> <td>{@link State#Initialized Initialized}<sup><a href="#streamworker">1</a></sup>, {@link State#Uninitialized Uninitialized}</td> <td>{@link GLMediaEventListener#EVENT_CHANGE_INIT EVENT_CHANGE_INIT} or ( {@link GLMediaEventListener#EVENT_CHANGE_ERR EVENT_CHANGE_ERR} + {@link GLMediaEventListener#EVENT_CHANGE_UNINIT EVENT_CHANGE_UNINIT} )</td></tr> * <tr><td>{@link #initGL(GL)}</td> <td>{@link State#Initialized Initialized}</td> <td>{@link State#Paused Paused}, , {@link State#Uninitialized Uninitialized}</td> <td>{@link GLMediaEventListener#EVENT_CHANGE_PAUSE EVENT_CHANGE_PAUSE} or ( {@link GLMediaEventListener#EVENT_CHANGE_ERR EVENT_CHANGE_ERR} + {@link GLMediaEventListener#EVENT_CHANGE_UNINIT EVENT_CHANGE_UNINIT} )</td></tr> * <tr><td>{@link #play()}</td> <td>{@link State#Paused Paused}</td> <td>{@link State#Playing Playing}</td> <td>{@link GLMediaEventListener#EVENT_CHANGE_PLAY EVENT_CHANGE_PLAY}</td></tr> - * <tr><td>{@link #pause()}</td> <td>{@link State#Playing Playing}</td> <td>{@link State#Paused Paused}</td> <td>{@link GLMediaEventListener#EVENT_CHANGE_PAUSE EVENT_CHANGE_PAUSE}</td></tr> + * <tr><td>{@link #pause(boolean)}</td> <td>{@link State#Playing Playing}</td> <td>{@link State#Paused Paused}</td> <td>{@link GLMediaEventListener#EVENT_CHANGE_PAUSE EVENT_CHANGE_PAUSE}</td></tr> * <tr><td>{@link #seek(int)}</td> <td>{@link State#Paused Paused}, {@link State#Playing Playing}</td> <td>{@link State#Paused Paused}, {@link State#Playing Playing}</td> <td>none</td></tr> * <tr><td>{@link #getNextTexture(GL)}</td> <td>{@link State#Paused Paused}, {@link State#Playing Playing}</td> <td>{@link State#Paused Paused}, {@link State#Playing Playing}</td> <td>none</td></tr> * <tr><td>{@link #getLastTexture()}</td> <td>{@link State#Paused Paused}, {@link State#Playing Playing}</td> <td>{@link State#Paused Paused}, {@link State#Playing Playing}</td> <td>none</td></tr> @@ -427,18 +427,34 @@ public interface GLMediaPlayer extends TextureSequence { public float getAudioVolume(); /** + * Starts or resumes the <i>StreamWorker</i> decoding thread. + * <p> * <a href="#lifecycle">Lifecycle</a>: {@link State#Paused} -> {@link State#Playing} + * </p> */ public State play(); /** + * Pauses the <i>StreamWorker</i> decoding thread. + * <p> * <a href="#lifecycle">Lifecycle</a>: {@link State#Playing} -> {@link State#Paused} + * </p> + * <p> + * If a <i>new</i> frame is desired after the next {@link #play()} call, + * e.g. to make a snapshot of a camera input stream, + * <code>flush</code> shall be set to <code>true</code>. + * </p> + * @param flush if <code>true</code> flushes the video and audio buffers, otherwise keep them intact. */ - public State pause(); + public State pause(boolean flush); /** + * Seeks to the new absolute position. The <i>StreamWorker</i> decoding thread + * is paused while doing so and the A/V buffers are flushed. + * <p> * Allowed in state {@link State#Playing} and {@link State#Paused}, otherwise ignored, - * see <a href="#lifecycle">Lifecycle</a>. + * see <a href="#lifecycle">Lifecycle</a>. + * </p> * * @param msec absolute desired time position in milliseconds * @return time current position in milliseconds, after seeking to the desired position diff --git a/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java b/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java index 205642eb0..40fa9c9d6 100644 --- a/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java +++ b/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java @@ -296,7 +296,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { switch( state ) { case Paused: if( playImpl() ) { - resetAudioVideoPTS(); + resetAVPTS(); if( null != audioSink ) { audioSink.play(); // cont. w/ new data } @@ -312,17 +312,19 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { protected abstract boolean playImpl(); @Override - public final State pause() { - return pauseImpl(0); + public final State pause(boolean flush) { + return pauseImpl(flush, 0); } - private final State pauseImpl(int event_mask) { + private final State pauseImpl(boolean flush, int event_mask) { synchronized( stateLock ) { final State preState = state; if( State.Playing == state ) { event_mask = addStateEventMask(event_mask, GLMediaPlayer.State.Paused); state = State.Paused; streamWorker.doPause(); - if( null != audioSink ) { + if( flush ) { + resetAVPTSAndFlush(); + } else if( null != audioSink ) { audioSink.pause(); } attributesUpdated( event_mask ); @@ -365,7 +367,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { state = State.Paused; streamWorker.doPause(); pts1 = seekImpl(msec); - resetAllAudioVideoSync(); + resetAVPTSAndFlush(); if( null != audioSink && State.Playing == _state ) { audioSink.play(); // cont. w/ new data } @@ -398,7 +400,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { rate = 1.0f; } if( setPlaySpeedImpl(rate) ) { - resetAudioVideoPTS(); + resetAVPTS(); playSpeed = rate; res = true; } @@ -738,7 +740,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { presentedFrameCount++; final int video_pts = nextFrame.getPTS(); if( video_pts == TimeFrameI.END_OF_STREAM_PTS ) { - pauseImpl(GLMediaEventListener.EVENT_CHANGE_EOS); + pauseImpl(true, GLMediaEventListener.EVENT_CHANGE_EOS); } else if( video_pts != TimeFrameI.INVALID_PTS ) { final int audio_pts = getAudioPTSImpl(); final int audio_scr = (int) ( ( currentTimeMillis - audio_scr_t0 ) * playSpeed ); @@ -855,7 +857,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { * {@inheritDoc} * <p> * Note: All {@link AudioSink} operations are performed from {@link GLMediaPlayerImpl}, - * i.e. {@link #play()}, {@link #pause()}, {@link #seek(int)}, {@link #setPlaySpeed(float)}, {@link #getAudioPTS()}. + * i.e. {@link #play()}, {@link #pause(boolean)}, {@link #seek(int)}, {@link #setPlaySpeed(float)}, {@link #getAudioPTS()}. * </p> * <p> * Implementations using an {@link AudioSink} shall write it's instance to {@link #audioSink} @@ -887,16 +889,16 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { } cachedFrame = null; } - private void resetAllAudioVideoSync() { + private void resetAVPTSAndFlush() { video_dpts_cum = 0; video_dpts_count = 0; - resetAudioVideoPTS(); + resetAVPTS(); flushAllVideoFrames(); if( null != audioSink ) { audioSink.flush(); } } - private void resetAudioVideoPTS() { + private void resetAVPTS() { presentedFrameCount = 0; displayedFrameCount = 0; decodedFrameCount = 0; @@ -1129,7 +1131,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { // state transition incl. notification shallPause = true; isActive = false; - pauseImpl(GLMediaEventListener.EVENT_CHANGE_EOS); + pauseImpl(true, GLMediaEventListener.EVENT_CHANGE_EOS); } } } @@ -1153,7 +1155,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer { // state transition incl. notification shallPause = true; isActive = false; - pauseImpl(GLMediaEventListener.EVENT_CHANGE_ERR); + pauseImpl(true, GLMediaEventListener.EVENT_CHANGE_ERR); } } } 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 57da78131..d10bba8c7 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 @@ -130,7 +130,7 @@ public class MovieCube implements GLEventListener { if(GLMediaPlayer.State.Paused == mPlayer.getState()) { mPlayer.play(); } else { - mPlayer.pause(); + mPlayer.pause(false); } break; } 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 b52e1fb21..907813191 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 @@ -124,7 +124,7 @@ public class MovieSimple implements GLEventListener { public void mousePressed(MouseEvent e) { if(e.getY()<=winHeight/2 && null!=mPlayer && 1 == e.getClickCount()) { if(GLMediaPlayer.State.Playing == mPlayer.getState()) { - mPlayer.pause(); + mPlayer.pause(false); } else { mPlayer.play(); } @@ -190,7 +190,7 @@ public class MovieSimple implements GLEventListener { if(GLMediaPlayer.State.Paused == mPlayer.getState()) { mPlayer.play(); } else { - mPlayer.pause(); + mPlayer.pause(false); } break; } |