summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2013-08-31 16:40:44 +0200
committerSven Gothel <[email protected]>2013-08-31 16:40:44 +0200
commit14d2d6865ebcfd8f4c1bdb1600f29fc2b1a4366d (patch)
tree8c1b2c9b0e7e758d0d5c9ba9771a6e456b5bef30
parent658493d2cdceeb9a61d6c40b3d8f7354ce0d7534 (diff)
GLMediaPlayer: pause() -> pause(boolean flush): Allowing to flush buffers, next frame after play() will provide new frame. Added API doc.
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java22
-rw-r--r--src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java30
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java4
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;
}