aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/com/jogamp/opengl
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2013-08-30 17:31:34 +0200
committerSven Gothel <[email protected]>2013-08-30 17:31:34 +0200
commit4cb3763415bb5f82520fd02f56412076f80a84e6 (patch)
tree33f864d513f9c94a3514cb9fab38fd1130ce9d32 /src/jogl/classes/com/jogamp/opengl
parentad4797e6875d8fc635971ed6d8dd68326c083540 (diff)
GLMediaPlayer enhancements: State, Camera options, detect and act on orientation change (flipped), API-doc,
- State - Fix state transition (initGL() error) - Camera options - options uses ';' as query separator - don't use 'default' options, driver should know - Detect and act on orientation change (flipped) - ffmpeg impl detects if flipped changes and triggers a SIZE update event. This allows application to react, i.e. re-init GL and use new TextureCoord's. Test: Works well on Windows w/ rawvideo dshow camera driver/codec. - API-doc - TexSeqEventListener/GLMediaEventListener usage / constraints (GL, ..) - State transition fix
Diffstat (limited to 'src/jogl/classes/com/jogamp/opengl')
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java50
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/TextureSequence.java23
2 files changed, 65 insertions, 8 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 1fb0608fb..5072c410d 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java
@@ -34,6 +34,7 @@ import javax.media.opengl.GLException;
import jogamp.opengl.Debug;
+import com.jogamp.opengl.util.texture.Texture;
import com.jogamp.opengl.util.texture.TextureSequence;
import com.jogamp.opengl.util.TimeFrameI;
@@ -81,8 +82,8 @@ import com.jogamp.opengl.util.TimeFrameI;
* <p>
* <table border="1">
* <tr><th>Action</th> <th>{@link State} Before</th> <th>{@link State} After</th> <th>{@link GLMediaEventListener Event}</th></tr>
- * <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#Initialized Initialized}</td> <td>{@link GLMediaEventListener#EVENT_CHANGE_PAUSE EVENT_CHANGE_PAUSE}</td></tr>
+ * <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 #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>
@@ -205,12 +206,14 @@ public interface GLMediaPlayer extends TextureSequence {
* ranging from [0..<i>max-number</i>].
* </p>
* <p>
- * The {@link URI#getRawQuery() URI query} is used to pass options to the camera.
+ * The {@link URI#getRawQuery() URI query} is used to pass options to the camera
+ * using <i>;</i> as the separator. The latter avoids trouble w/ escaping.
* </p>
* <pre>
* camera:/<id>
* camera://somewhere/<id>
- * camera://somewhere/<id>?width=640&height=480&rate=15
+ * camera://somewhere/<id>?width=640;height=480;rate=15
+ * camera://somewhere/<id>?size=640x480;rate=15
* </pre>
* <pre>
* URI: [scheme:][//authority][path][?query][#fragment]
@@ -245,6 +248,13 @@ public interface GLMediaPlayer extends TextureSequence {
super(message, cause);
}
}
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * See {@link TexSeqEventListener} for semantics and usage.
+ * </p>
+ */
public interface GLMediaEventListener extends TexSeqEventListener<GLMediaPlayer> {
/** State changed to {@link State#Initialized}. See <a href="#lifecycle">Lifecycle</a>.*/
@@ -264,7 +274,7 @@ public interface GLMediaPlayer extends TextureSequence {
static final int EVENT_CHANGE_VID = 1<<16;
/** Stream audio id change. */
static final int EVENT_CHANGE_AID = 1<<17;
- /** TextureFrame size change. */
+ /** TextureFrame size or vertical flip change. */
static final int EVENT_CHANGE_SIZE = 1<<18;
/** Stream fps change. */
static final int EVENT_CHANGE_FPS = 1<<19;
@@ -556,18 +566,44 @@ public interface GLMediaPlayer extends TextureSequence {
*/
public float getFramerate();
+ /**
+ * Returns <code>true</code> if the video frame is oriented in
+ * OpenGL's coordinate system, <i>origin at bottom left</i>.
+ * <p>
+ * Otherwise returns <code>false</code>, i.e.
+ * video frame is oriented <i>origin at top left</i>.
+ * </p>
+ * <p>
+ * <code>false</code> is the default assumption for videos,
+ * but user shall not rely on.
+ * </p>
+ * <p>
+ * <code>false</code> GL orientation leads to
+ * {@link Texture#getMustFlipVertically()} == <code>true</code>,
+ * as reflected by all {@link TextureFrame}'s {@link Texture}s
+ * retrieved via {@link #getLastTexture()} or {@link #getNextTexture(GL)}.
+ * </p>
+ */
+ public boolean isGLOriented();
+
+ /** Returns the width of the video. */
public int getWidth();
+ /** Returns the height of the video. */
public int getHeight();
+ /** Returns a string represantation of this player, incl. state and audio/video details. */
public String toString();
+ /** Returns a string represantation of this player's performance values. */
public String getPerfString();
+ /** Adds a {@link GLMediaEventListener} to this player. */
public void addEventListener(GLMediaEventListener l);
+ /** Removes a {@link GLMediaEventListener} to this player. */
public void removeEventListener(GLMediaEventListener l);
- public GLMediaEventListener[] getEventListeners();
-
+ /** Return all {@link GLMediaEventListener} of this player. */
+ public GLMediaEventListener[] getEventListeners();
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureSequence.java b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureSequence.java
index 8b6cc1bf9..5c6b63535 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureSequence.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureSequence.java
@@ -28,7 +28,9 @@
package com.jogamp.opengl.util.texture;
import javax.media.opengl.GL;
-
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLRunnable;
+import javax.media.opengl.GLEventListener;
import com.jogamp.opengl.util.TimeFrameI;
/**
@@ -128,6 +130,25 @@ public interface TextureSequence {
protected final Texture texture;
}
+ /**
+ * Event listener to notify users of updates regarding the {@link TextureSequence}.
+ * <p>
+ * The implementation sending the events, and hence calling down to all listeners,
+ * does not necessarily make the user's OpenGL context current.
+ * </p>
+ * <p>
+ * Further more, the call may happen off-thread, possibly holding another, possibly shared, OpenGL context current.
+ * </p>
+ * Hence a user shall not issue <i>any</i> OpenGL, time consuming
+ * or {@link TextureSequence} lifecycle operations directly.<br>
+ * Instead, the user shall:
+ * <ul>
+ * <li>issue commands off-thread via spawning off another thread, or</li>
+ * <li>injecting {@link GLRunnable} objects via {@link GLAutoDrawable#invoke(boolean, GLRunnable)}, or</li>
+ * <li>simply changing a volatile state of their {@link GLEventListener} implementation.</li>
+ * </ul>
+ * </p>
+ * */
public interface TexSeqEventListener<T extends TextureSequence> {
/**
* Signaling listeners that a new {@link TextureFrame} is available.