diff options
author | Sven Gothel <[email protected]> | 2013-08-10 09:14:19 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2013-08-10 09:14:19 +0200 |
commit | 6332e13b2f0aa9818d37802302f04c90a4fa4239 (patch) | |
tree | b615630b4a886270721f82636a323ec36dac341c /src/jogl/classes/com/jogamp/opengl | |
parent | 590d78dc2ff24ce80976a30e35a99c06ef6750b0 (diff) |
GLMediaPlayer: Add multithreaded decoding w/ textureCount > 2 where available EGL/FFMPeg. WIP!
Off-thread decoding:
If validated (impl) textureCount > 2, decoding happens on extra thread.
If decoding requires GL context, a shared context is created for decoding thread.
API Changes:
- initGLStream(..): Adds 'textureCount' as argument.
- TextureSequence.TexSeqEventListener.newFrameAvailable(..) exposes the new frame available
- TextureSequence.TextureFrame exposes the PTS (video)
Implementation:
- 'int validateTextureCount(int)': implementation decides whether textureCount can be > 2, i.e. off-thread decoding allowed,
default is NO w/ textureCount==2!
- 'boolean requiresOffthreadGLCtx()': implementation decides whether shared context is required for off-thread decoding
- 'syncFrame2Audio(TextureFrame frame)': implementation shall handle a/v sync, due to audio stream details (pts, buffered frames)
- FFMPEGMediaPlayer extends GLMediaPlayerImpl, no more EGLMediaPlayerImpl (redundant)
+++
- SyncedRingbuffer: Expose T[] array
+++
TODO:
- syncAV!
- test Android
Diffstat (limited to 'src/jogl/classes/com/jogamp/opengl')
3 files changed, 43 insertions, 17 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 1825dbd47..a36bce305 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java +++ b/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java @@ -40,12 +40,12 @@ import com.jogamp.opengl.util.texture.TextureSequence; /** * Lifecycle of an GLMediaPlayer: * <table border="1"> - * <tr><th>action</th> <th>state before</th> <th>state after</th></tr> - * <tr><td>{@link #initGLStream(GL, URLConnection)}</td> <td>Uninitialized</td> <td>Stopped</td></tr> - * <tr><td>{@link #start()}</td> <td>Stopped, Paused</td> <td>Playing</td></tr> - * <tr><td>{@link #stop()}</td> <td>Playing, Paused</td> <td>Stopped</td></tr> - * <tr><td>{@link #pause()}</td> <td>Playing</td> <td>Paused</td></tr> - * <tr><td>{@link #destroy(GL)}</td> <td>ANY</td> <td>Uninitialized</td></tr> + * <tr><th>action</th> <th>state before</th> <th>state after</th></tr> + * <tr><td>{@link #initGLStream(GL, int, URLConnection)}</td> <td>Uninitialized</td> <td>Stopped</td></tr> + * <tr><td>{@link #start()}</td> <td>Stopped, Paused</td> <td>Playing</td></tr> + * <tr><td>{@link #stop()}</td> <td>Playing, Paused</td> <td>Stopped</td></tr> + * <tr><td>{@link #pause()}</td> <td>Playing</td> <td>Paused</td></tr> + * <tr><td>{@link #destroy(GL)}</td> <td>ANY</td> <td>Uninitialized</td></tr> * </table> * <p> * Current implementations (check each API doc link for details): @@ -105,8 +105,12 @@ public interface GLMediaPlayer extends TextureSequence { public int getTextureCount(); - /** Defaults to 0 */ + /** Returns the texture target used by implementation. */ + public int getTextureTarget(); + + /** Sets the texture unit. Defaults to 0. */ public void setTextureUnit(int u); + /** Sets the texture min-mag filter, defaults to {@link GL#GL_NEAREST}. */ public void setTextureMinMagFilter(int[] minMagFilter); /** Sets the texture min-mag filter, defaults to {@link GL#GL_CLAMP_TO_EDGE}. */ @@ -119,6 +123,7 @@ public interface GLMediaPlayer extends TextureSequence { * Uninitialized -> Stopped * </p> * @param gl current GL object. If null, no video output and textures will be available. + * @param textureCount desired number of buffered textures to be decoded off-thread, use <code>1</code> for on-thread decoding. * @param urlConn the stream connection * @return the new state * @@ -126,7 +131,7 @@ public interface GLMediaPlayer extends TextureSequence { * @throws IOException in case of difficulties to open or process the stream * @throws GLException in case of difficulties to initialize the GL resources */ - public State initGLStream(GL gl, URLConnection urlConn) throws IllegalStateException, GLException, IOException; + public State initGLStream(GL gl, int textureCount, URLConnection urlConn) throws IllegalStateException, GLException, IOException; /** * Releases the GL and stream resources. @@ -161,11 +166,21 @@ public interface GLMediaPlayer extends TextureSequence { public State getState(); /** - * @return time current position in milliseconds + * @return current streaming position in milliseconds **/ public int getCurrentPosition(); /** + * @return current video PTS in milliseconds of {@link #getLastTexture()} + **/ + public int getVideoPTS(); + + /** + * @return current audio PTS in milliseconds. + **/ + public int getAudioPTS(); + + /** * Allowed in state Stopped, Playing and Paused, otherwise ignored. * * @param msec absolute desired time position in milliseconds @@ -187,7 +202,7 @@ public interface GLMediaPlayer extends TextureSequence { * </p> * * @see #addEventListener(GLMediaEventListener) - * @see GLMediaEventListener#newFrameAvailable(GLMediaPlayer, long) + * @see GLMediaEventListener#newFrameAvailable(GLMediaPlayer, TextureFrame, long) */ @Override public TextureSequence.TextureFrame getNextTexture(GL gl, boolean blocking) throws IllegalStateException; diff --git a/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayerFactory.java b/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayerFactory.java index f09531f7f..2707dd6d2 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayerFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayerFactory.java @@ -29,18 +29,20 @@ package com.jogamp.opengl.util.av; import jogamp.opengl.util.av.NullGLMediaPlayer; -import com.jogamp.common.os.AndroidVersion; -import com.jogamp.common.os.Platform; import com.jogamp.common.util.ReflectionUtil; public class GLMediaPlayerFactory { private static final String AndroidGLMediaPlayerAPI14ClazzName = "jogamp.opengl.android.av.AndroidGLMediaPlayerAPI14"; private static final String FFMPEGMediaPlayerClazzName = "jogamp.opengl.util.av.impl.FFMPEGMediaPlayer"; + private static final String OMXGLMediaPlayerClazzName = "jogamp.opengl.util.av.impl.OMXGLMediaPlayer"; private static final String isAvailableMethodName = "isAvailable"; public static GLMediaPlayer createDefault() { final ClassLoader cl = GLMediaPlayerFactory.class.getClassLoader(); - GLMediaPlayer sink = create(cl, AndroidGLMediaPlayerAPI14ClazzName); + GLMediaPlayer sink = create(cl, OMXGLMediaPlayerClazzName); + if( null == sink ) { + sink = create(cl, AndroidGLMediaPlayerAPI14ClazzName); + } if( null == sink ) { sink = create(cl, FFMPEGMediaPlayerClazzName); } 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 9f951d5da..3f739b2cc 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureSequence.java +++ b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureSequence.java @@ -112,26 +112,35 @@ public interface TextureSequence { public static class TextureFrame { public TextureFrame(Texture t) { texture = t; + pts = 0; } public final Texture getTexture() { return texture; } + public final int getPTS() { return pts; } + public final void setPTS(int pts) { this.pts = pts; } public String toString() { - return "TextureFrame[" + texture + "]"; + return "TextureFrame[" + pts + "ms: " + texture + "]"; } protected final Texture texture; + protected int pts; } public interface TexSeqEventListener<T extends TextureSequence> { /** - * Signaling listeners that {@link TextureSequence#getNextTexture(GL, boolean)} is able to deliver a new frame. + * Signaling listeners that a new {@link TextureFrame} is available. + * <p> + * User shall utilize {@link TextureSequence#getNextTexture(GL, boolean)} to dequeue it to maintain + * a consistent queue. + * </p> * @param ts the event source + * @param newFrame the newly enqueued frame * @param when system time in msec. **/ - public void newFrameAvailable(T ts, long when); + public void newFrameAvailable(T ts, TextureFrame newFrame, long when); } - /** Return the texture unit to be used with this frame. */ + /** Return the texture unit used to render the current frame. */ public int getTextureUnit(); public int[] getTextureMinMagFilter(); |