diff options
author | Sven Gothel <[email protected]> | 2013-08-14 07:02:59 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2013-08-14 07:02:59 +0200 |
commit | c37629ea8fdcb11f7f8a18e37a4cde57d4ba6a01 (patch) | |
tree | 96e6ef2b8db44f3dd331ac78a0a52d5d5ea15e50 /src/test | |
parent | bc3776633ccad81199a96ff8116195133d862395 (diff) |
GLMediaPlayer Multithreaded Decoding: GLMediaPlayer* (Part-3) - WIP
- GLMediaPlayer
- Remove State.Stopped and method stop() - redundant, use pause() / destroy()
- Add notion of stream IDs
- Add API doc: State / Stream-ID incl. html-anchor
- Expose video/audio PTS, ..
- Expose optional AudioSink
- Min multithreaded textureCount is 4 (EGL* and FFMPEG*)
- GLMediaPlayerImpl
- Move AudioSink rel. impl. to this class,
allowing a tight video implementation reusing logic.
- Remove 'synchronized' methods, synchronize on State
where applicable
- implement new methods (see above)
- playSpeed is handled partially in AudioSink.
If it exeeds AudioSink's capabilities, drop audio and rely solely on video sync.
- video sync (WIP)
- video pts delay based on geometric weight
- reset video SCR if 'out of range', resync w/ PTS
-
- FramePusher
- allow interruption when pausing/stopping,
while waiting for next avail free frame to decode.
- FFMPEGMediaPlayer
- Add proper AudioDataFormat negotiation AudioSink <-> libav
- Parse libav's SampleFormat
- Remove AudioSink interaction (moved to GLMediaPlayerImpl)
- Tests (MovieSimple, MovieCube):
- Add aid/vid selection
- Add KeyListener for actions: seek(..), play()/pause(), setPlaySpeed(..)
- Dump perf-string each 2s
- TODO:
- Add audio sync in AudioSink, similar to GLMediaPlayer's weighted video delay,
here: drop audio frames.
Diffstat (limited to 'src/test')
6 files changed, 295 insertions, 123 deletions
diff --git a/src/test/com/jogamp/opengl/test/android/MovieCubeActivity0.java b/src/test/com/jogamp/opengl/test/android/MovieCubeActivity0.java index 3e61e509c..e905bfeab 100644 --- a/src/test/com/jogamp/opengl/test/android/MovieCubeActivity0.java +++ b/src/test/com/jogamp/opengl/test/android/MovieCubeActivity0.java @@ -44,6 +44,7 @@ import com.jogamp.newt.opengl.GLWindow; import com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieCube; import com.jogamp.opengl.util.Animator; +import com.jogamp.opengl.util.av.GLMediaPlayer; import android.os.Bundle; import android.util.Log; @@ -84,7 +85,7 @@ public class MovieCubeActivity0 extends NewtBaseActivity { final Animator animator = new Animator(); // Main - final MovieCube demoMain = new MovieCube(urlConnection0, -2.3f, 0f, 0f); + final MovieCube demoMain = new MovieCube(urlConnection0, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, -2.3f, 0f, 0f); final GLWindow glWindowMain = GLWindow.create(scrn, capsMain); glWindowMain.setFullscreen(true); setContentView(getWindow(), glWindowMain); diff --git a/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity0.java b/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity0.java index bcff3d5bd..7a92360fb 100644 --- a/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity0.java +++ b/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity0.java @@ -45,6 +45,7 @@ import com.jogamp.newt.opengl.GLWindow; import com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieSimple; import com.jogamp.opengl.util.Animator; +import com.jogamp.opengl.util.av.GLMediaPlayer; import android.os.Bundle; import android.util.Log; @@ -84,7 +85,7 @@ public class MovieSimpleActivity0 extends NewtBaseActivity { final Animator animator = new Animator(); // Main - final MovieSimple demoMain = new MovieSimple(urlConnection0); + final MovieSimple demoMain = new MovieSimple(urlConnection0, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO); demoMain.setScaleOrig(true); final GLWindow glWindowMain = GLWindow.create(scrn, capsMain); glWindowMain.setFullscreen(true); diff --git a/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity1.java b/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity1.java index cb0fd0720..d0fb41828 100644 --- a/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity1.java +++ b/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity1.java @@ -111,7 +111,7 @@ public class MovieSimpleActivity1 extends NewtBaseActivity { final Animator animator = new Animator(); // Main - final MovieSimple demoMain = new MovieSimple(urlConnection0); + final MovieSimple demoMain = new MovieSimple(urlConnection0, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO); if(mPlayerHUD) { demoMain.setEffects(MovieSimple.EFFECT_GRADIENT_BOTTOM2TOP); demoMain.setTransparency(0.9f); @@ -154,7 +154,7 @@ public class MovieSimpleActivity1 extends NewtBaseActivity { glWindowHUD.addGLEventListener(new MovieSimple(sharedPlayer)); } else { try { - glWindowHUD.addGLEventListener(new MovieSimple(urlConnection1)); + glWindowHUD.addGLEventListener(new MovieSimple(urlConnection1, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO)); } catch (IOException e) { e.printStackTrace(); } diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureSequenceCubeES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureSequenceCubeES2.java index adccecba0..556d17992 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureSequenceCubeES2.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureSequenceCubeES2.java @@ -332,22 +332,32 @@ public class TextureSequenceCubeES2 implements GLEventListener { } + @Override public void dispose(GLAutoDrawable drawable) { GL2ES2 gl = drawable.getGL().getGL2ES2(); texSeq = null; pmvMatrixUniform = null; - pmvMatrix.destroy(); - pmvMatrix=null; - st.destroy(gl); - st=null; + if( null != pmvMatrix ) { + pmvMatrix.destroy(); + pmvMatrix=null; + } + if( null != st ) { + st.destroy(gl); + st=null; + } } + @Override public void display(GLAutoDrawable drawable) { GL2ES2 gl = drawable.getGL().getGL2ES2(); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); - + + if( null == st ) { + return; + } + st.useProgram(gl, true); pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); @@ -379,9 +389,6 @@ public class TextureSequenceCubeES2 implements GLEventListener { st.useProgram(gl, false); } - public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) { - } - static final float[] light_position = { -50.f, 50.f, 50.f, 0.f }; static final float[] light_ambient = { 0.125f, 0.125f, 0.125f, 1.f }; static final float[] light_diffuse = { 1.0f, 1.0f, 1.0f, 1.f }; 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 3f979e16f..fbbd77260 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 @@ -57,6 +57,7 @@ import com.jogamp.newt.opengl.GLWindow; import com.jogamp.opengl.JoglVersion; import com.jogamp.opengl.test.junit.jogl.demos.es2.TextureSequenceCubeES2; import com.jogamp.opengl.test.junit.util.MiscUtils; +import com.jogamp.opengl.test.junit.util.UITestCase; import com.jogamp.opengl.util.Animator; import com.jogamp.opengl.util.av.GLMediaPlayer; import com.jogamp.opengl.util.av.GLMediaPlayer.GLMediaEventListener; @@ -67,20 +68,25 @@ public class MovieCube implements GLEventListener, GLMediaEventListener { static boolean waitForKey = false; int textureCount = 3; // default - threaded final URLConnection stream; + final int vid, aid; final float zoom0, rotx, roty; TextureSequenceCubeES2 cube=null; GLMediaPlayer mPlayer=null; public MovieCube() throws IOException { this(new URL("http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4").openConnection(), - -2.3f, 0f, 0f); + GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, -2.3f, 0f, 0f); } - public MovieCube(URLConnection stream, float zoom0, float rotx, float roty) throws IOException { + public MovieCube(URLConnection stream, int vid, int aid, float zoom0, float rotx, float roty) throws IOException { this.stream = stream; this.zoom0 = zoom0; this.rotx = rotx; this.roty = roty; + this.vid = vid; + this.aid = aid; + mPlayer = GLMediaPlayerFactory.createDefault(); + mPlayer.addEventListener(this); } public void setTextureCount(int v) { @@ -89,11 +95,11 @@ public class MovieCube implements GLEventListener, GLMediaEventListener { private final KeyListener keyAction = new KeyAdapter() { public void keyReleased(KeyEvent e) { - if( !e.isPrintableKey() || e.isAutoRepeat() ) { + if( e.isAutoRepeat() ) { return; } System.err.println("MC "+e); - int pts0 = mPlayer.getCurrentPosition(); + int pts0 = mPlayer.getVideoPTS(); int pts1 = 0; switch(e.getKeyCode()) { case KeyEvent.VK_3: @@ -107,21 +113,37 @@ public class MovieCube implements GLEventListener, GLMediaEventListener { case KeyEvent.VK_ESCAPE: case KeyEvent.VK_DELETE: case KeyEvent.VK_BACK_SPACE: { - mPlayer.seek(0); mPlayer.setPlaySpeed(1.0f); - mPlayer.start(); + mPlayer.seek(0); + mPlayer.play(); break; } case KeyEvent.VK_SPACE: { if(GLMediaPlayer.State.Paused == mPlayer.getState()) { - mPlayer.start(); + mPlayer.play(); } else { mPlayer.pause(); } break; } - case KeyEvent.VK_S: mPlayer.setPlaySpeed(mPlayer.getPlaySpeed()/2.0f); break; - case KeyEvent.VK_F: mPlayer.setPlaySpeed(mPlayer.getPlaySpeed()*2.0f); break; + case KeyEvent.VK_SUBTRACT: { + float playSpeed = mPlayer.getPlaySpeed(); + if( e.isShiftDown() ) { + playSpeed /= 2.0f; + } else { + playSpeed -= 0.1f; + } + mPlayer.setPlaySpeed(playSpeed); + } break; + case KeyEvent.VK_ADD: { + float playSpeed = mPlayer.getPlaySpeed(); + if( e.isShiftDown() ) { + playSpeed *= 2.0f; + } else { + playSpeed += 0.1f; + } + mPlayer.setPlaySpeed(playSpeed); + } break; } if( 0 != pts1 ) { @@ -140,25 +162,18 @@ public class MovieCube implements GLEventListener, GLMediaEventListener { // System.out.println("newFrameAvailable: "+mp+", when "+when); } + @Override public void init(GLAutoDrawable drawable) { GL2ES2 gl = drawable.getGL().getGL2ES2(); System.err.println(JoglVersion.getGLInfo(gl, null)); - mPlayer = GLMediaPlayerFactory.createDefault(); - mPlayer.addEventListener(this); cube = new TextureSequenceCubeES2(mPlayer, false, zoom0, rotx, roty); if(waitForKey) { - BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); - System.err.println("Press enter to continue"); - try { - System.err.println(stdin.readLine()); - } catch (IOException e) { } + UITestCase.waitForKey("Init>"); } try { - System.out.println("p0 "+mPlayer); - mPlayer.initGLStream(gl, textureCount, stream); - System.out.println("p1 "+mPlayer); + mPlayer.initGLStream(gl, textureCount, stream, vid, aid); } catch (Exception e) { e.printStackTrace(); if(null != mPlayer) { @@ -169,7 +184,7 @@ public class MovieCube implements GLEventListener, GLMediaEventListener { } cube.init(drawable); - mPlayer.start(); + mPlayer.play(); boolean added; final Object upstreamWidget = drawable.getUpstreamWidget(); @@ -181,30 +196,38 @@ public class MovieCube implements GLEventListener, GLMediaEventListener { System.err.println("MC.init: kl-added "+added+", "+drawable.getClass().getName()); } + @Override public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { if(null == mPlayer) { return; } cube.reshape(drawable, x, y, width, height); } + @Override public void dispose(GLAutoDrawable drawable) { System.err.println(Thread.currentThread()+" MovieCube.dispose ... "); if(null == mPlayer) { return; } - mPlayer.stop(); - GL2ES2 gl = drawable.getGL().getGL2ES2(); + final GL2ES2 gl = drawable.getGL().getGL2ES2(); mPlayer.destroy(gl); mPlayer=null; cube.dispose(drawable); cube=null; } + long lastPerfPos = 0; + + @Override public void display(GLAutoDrawable drawable) { if(null == mPlayer) { return; } + + final long currentPos = System.currentTimeMillis(); + if( currentPos - lastPerfPos > 2000 ) { + System.err.println( mPlayer.getPerfString() ); + lastPerfPos = currentPos; + } + cube.display(drawable); } - public void displayChanged(javax.media.opengl.GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) { - } - public static void main(String[] args) throws MalformedURLException, IOException, InterruptedException { int width = 510; int height = 300; @@ -214,40 +237,56 @@ public class MovieCube implements GLEventListener, GLMediaEventListener { boolean forceES3 = false; boolean forceGL3 = false; boolean forceGLDef = false; + int vid = GLMediaPlayer.STREAM_ID_AUTO; + int aid = GLMediaPlayer.STREAM_ID_AUTO; + final boolean origSize; - String url_s="http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4"; - for(int i=0; i<args.length; i++) { - if(args[i].equals("-width")) { - i++; - width = MiscUtils.atoi(args[i], width); - } else if(args[i].equals("-height")) { - i++; - height = MiscUtils.atoi(args[i], height); - } else if(args[i].equals("-textureCount")) { - i++; - textureCount = MiscUtils.atoi(args[i], textureCount); - } else if(args[i].equals("-url")) { - i++; - url_s = args[i]; - } else if(args[i].equals("-es2")) { - forceES2 = true; - } else if(args[i].equals("-es3")) { - forceES3 = true; - } else if(args[i].equals("-gl3")) { - forceGL3 = true; - } else if(args[i].equals("-gldef")) { - forceGLDef = true; - } else if(args[i].equals("-wait")) { - waitForKey = true; + String url_s="http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4"; + { + boolean _origSize = false; + for(int i=0; i<args.length; i++) { + if(args[i].equals("-vid")) { + i++; + vid = MiscUtils.atoi(args[i], vid); + } else if(args[i].equals("-aid")) { + i++; + aid = MiscUtils.atoi(args[i], aid); + } else if(args[i].equals("-width")) { + i++; + width = MiscUtils.atoi(args[i], width); + } else if(args[i].equals("-height")) { + i++; + height = MiscUtils.atoi(args[i], height); + } else if(args[i].equals("-osize")) { + _origSize = true; + } else if(args[i].equals("-textureCount")) { + i++; + textureCount = MiscUtils.atoi(args[i], textureCount); + } else if(args[i].equals("-url")) { + i++; + url_s = args[i]; + } else if(args[i].equals("-es2")) { + forceES2 = true; + } else if(args[i].equals("-es3")) { + forceES3 = true; + } else if(args[i].equals("-gl3")) { + forceGL3 = true; + } else if(args[i].equals("-gldef")) { + forceGLDef = true; + } else if(args[i].equals("-wait")) { + waitForKey = true; + } } + origSize = _origSize; } + System.err.println("vid "+vid+", aid "+aid); System.err.println("textureCount "+textureCount); System.err.println("forceES2 "+forceES2); System.err.println("forceES3 "+forceES3); System.err.println("forceGL3 "+forceGL3); System.err.println("forceGLDef "+forceGLDef); - final MovieCube mc = new MovieCube(new URL(url_s).openConnection(), -2.3f, 0f, 0f); + final MovieCube mc = new MovieCube(new URL(url_s).openConnection(), vid, aid, -2.3f, 0f, 0f); final GLProfile glp; if(forceGLDef) { @@ -265,18 +304,30 @@ public class MovieCube implements GLEventListener, GLMediaEventListener { final GLWindow window = GLWindow.create(new GLCapabilities(glp)); // Size OpenGL to Video Surface window.setSize(width, height); - window.setFullscreen(false); - window.setSize(width, height); window.addGLEventListener(mc); + + mc.mPlayer.addEventListener(new GLMediaEventListener() { + @Override + public void newFrameAvailable(GLMediaPlayer ts, TextureFrame newFrame, long when) { + } + + @Override + public void attributesChanges(final GLMediaPlayer mp, int event_mask, long when) { + if( 0 != ( GLMediaEventListener.EVENT_CHANGE_SIZE & event_mask ) && origSize ) { + window.setSize(mp.getWidth(), mp.getHeight()); + } + } + }); + final Animator anim = new Animator(window); window.addWindowListener(new WindowAdapter() { public void windowDestroyed(WindowEvent e) { anim.stop(); } }); + window.setVisible(true); anim.setUpdateFPSFrames(60, System.err); anim.start(); - window.setVisible(true); } } 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 90c73661a..f5490d19a 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 @@ -46,6 +46,9 @@ import javax.media.opengl.GLUniformData; import javax.media.opengl.fixedfunc.GLMatrixFunc; import com.jogamp.newt.Window; +import com.jogamp.newt.event.KeyAdapter; +import com.jogamp.newt.event.KeyEvent; +import com.jogamp.newt.event.KeyListener; import com.jogamp.newt.event.MouseAdapter; import com.jogamp.newt.event.MouseEvent; import com.jogamp.newt.event.MouseListener; @@ -54,6 +57,7 @@ import com.jogamp.newt.event.WindowEvent; import com.jogamp.newt.opengl.GLWindow; import com.jogamp.opengl.JoglVersion; import com.jogamp.opengl.test.junit.util.MiscUtils; +import com.jogamp.opengl.test.junit.util.UITestCase; import com.jogamp.opengl.util.Animator; import com.jogamp.opengl.util.GLArrayDataServer; import com.jogamp.opengl.util.PMVMatrix; @@ -69,6 +73,7 @@ import com.jogamp.opengl.util.texture.TextureSequence; import com.jogamp.opengl.util.texture.TextureSequence.TextureFrame; public class MovieSimple implements GLEventListener, GLMediaEventListener { + static boolean waitForKey = false; private int winWidth, winHeight; int textureCount = 3; // default - threaded private int prevMouseX; // , prevMouseY; @@ -98,7 +103,8 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener { } GLMediaPlayer mPlayer; - URLConnection stream = null; + final URLConnection stream; + final int vid, aid; boolean mPlayerExternal; boolean mPlayerShared; boolean mPlayerScaleOrig; @@ -110,7 +116,7 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener { if(GLMediaPlayer.State.Playing == mPlayer.getState()) { mPlayer.pause(); } else { - mPlayer.start(); + mPlayer.play(); } } } @@ -131,9 +137,9 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener { if(y>winHeight/2) { final float dp = (float)(x-prevMouseX)/(float)winWidth; - mPlayer.seek(mPlayer.getCurrentPosition() + (int) (mPlayer.getDuration() * dp)); + mPlayer.seek(mPlayer.getVideoPTS() + (int) (mPlayer.getDuration() * dp)); } else { - mPlayer.start(); + mPlayer.play(); rotate = 1; zoom = zoom1; } @@ -149,13 +155,74 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener { } }; - public MovieSimple(URLConnection stream) throws IOException { + 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; + switch(e.getKeyCode()) { + case KeyEvent.VK_3: + case KeyEvent.VK_RIGHT: pts1 = pts0 + 1000; break; + case KeyEvent.VK_4: + case KeyEvent.VK_UP: pts1 = pts0 + 10000; break; + case KeyEvent.VK_2: + case KeyEvent.VK_LEFT: pts1 = pts0 - 1000; break; + case KeyEvent.VK_1: + case KeyEvent.VK_DOWN: pts1 = pts0 - 10000; break; + case KeyEvent.VK_ESCAPE: + case KeyEvent.VK_DELETE: + case KeyEvent.VK_BACK_SPACE: { + mPlayer.setPlaySpeed(1.0f); + mPlayer.seek(0); + mPlayer.play(); + break; + } + case KeyEvent.VK_SPACE: { + if(GLMediaPlayer.State.Paused == mPlayer.getState()) { + mPlayer.play(); + } else { + mPlayer.pause(); + } + break; + } + case KeyEvent.VK_SUBTRACT: { + float playSpeed = mPlayer.getPlaySpeed(); + if( e.isShiftDown() ) { + playSpeed /= 2.0f; + } else { + playSpeed -= 0.1f; + } + mPlayer.setPlaySpeed(playSpeed); + } break; + case KeyEvent.VK_ADD: { + float playSpeed = mPlayer.getPlaySpeed(); + if( e.isShiftDown() ) { + playSpeed *= 2.0f; + } else { + playSpeed += 0.1f; + } + mPlayer.setPlaySpeed(playSpeed); + } break; + } + + if( 0 != pts1 ) { + mPlayer.seek(pts1); + } + } + }; + + public MovieSimple(URLConnection stream, int vid, int aid) throws IOException { mPlayerScaleOrig = false; mPlayerShared = false; mPlayerExternal = false; mPlayer = GLMediaPlayerFactory.createDefault(); mPlayer.addEventListener(this); this.stream = stream; + this.vid = vid; + this.aid = aid; System.out.println("pC.1 "+mPlayer); } @@ -166,6 +233,8 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener { mPlayer = sharedMediaPlayer; mPlayer.addEventListener(this); this.stream = null; + this.vid = sharedMediaPlayer.getVID(); + this.aid = sharedMediaPlayer.getAID(); System.out.println("pC.2 shared "+mPlayerShared+", "+mPlayer); } @@ -188,20 +257,13 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener { // System.out.println("newFrameAvailable: "+mp+", when "+when); } - public void start() { + public void play() { if(null!=mPlayer) { - mPlayer.start(); + mPlayer.play(); System.out.println("pStart "+mPlayer); } } - public void stop() { - if(null!=mPlayer) { - mPlayer.stop(); - System.out.println("pStop "+mPlayer); - } - } - ShaderState st; PMVMatrix pmvMatrix; GLUniformData pmvMatrixUniform; @@ -242,6 +304,7 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener { st.attachShaderProgram(gl, sp, false); } + @Override public void init(GLAutoDrawable drawable) { zoom0 = orthoProjection ? 0f : -2.5f; zoom1 = orthoProjection ? 0f : -5f; @@ -252,12 +315,15 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener { System.err.println("Alpha: "+alpha+", opaque "+drawable.getChosenGLCapabilities().isBackgroundOpaque()+ ", "+drawable.getClass().getName()+", "+drawable); + if(waitForKey) { + UITestCase.waitForKey("Init>"); + } final Texture tex; boolean useExternalTexture = false; try { System.out.println("p0 "+mPlayer+", shared "+mPlayerShared); if(!mPlayerShared) { - mPlayer.initGLStream(gl, textureCount, stream); + mPlayer.initGLStream(gl, textureCount, stream, vid, aid); } tex = mPlayer.getLastTexture().getTexture(); System.out.println("p1 "+mPlayer+", shared "+mPlayerShared); @@ -392,7 +458,7 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener { System.out.println(st); if(null!=mPlayer) { - start(); + play(); System.out.println("p2 "+mPlayer); } @@ -402,11 +468,13 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener { if (upstreamWidget instanceof Window) { final Window window = (Window) upstreamWidget; window.addMouseListener(mouseAction); + window.addKeyListener(keyAction); winWidth = window.getWidth(); winHeight = window.getHeight(); } } + @Override public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { if(null == mPlayer) { return; } winWidth = width; @@ -442,34 +510,51 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener { pmvMatrix.glTranslatef(0, 0, zoom0); } + @Override public void dispose(GLAutoDrawable drawable) { if(null == mPlayer) { return; } - stop(); - System.out.println("pD.1 "+mPlayer); - + System.out.println("pD.1 "+mPlayer); GL2ES2 gl = drawable.getGL().getGL2ES2(); - - mPlayer.removeEventListener(this); - if(!mPlayerExternal) { - mPlayer.destroy(gl); + if( null != mPlayer ) { + mPlayer.removeEventListener(this); + if(!mPlayerExternal) { + mPlayer.destroy(gl); + } } System.out.println("pD.X "+mPlayer); mPlayer=null; pmvMatrixUniform = null; - pmvMatrix.destroy(); - pmvMatrix=null; - st.destroy(gl); - st=null; + if(null != pmvMatrix) { + pmvMatrix.destroy(); + pmvMatrix=null; + } + if(null != st) { + st.destroy(gl); + st=null; + } } + long lastPerfPos = 0; + + @Override public void display(GLAutoDrawable drawable) { if(null == mPlayer) { return; } + final long currentPos = System.currentTimeMillis(); + if( currentPos - lastPerfPos > 2000 ) { + System.err.println( mPlayer.getPerfString() ); + lastPerfPos = currentPos; + } + GL2ES2 gl = drawable.getGL().getGL2ES2(); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); + if(null == st) { + return; + } + st.useProgram(gl, true); pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); @@ -506,9 +591,6 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener { st.useProgram(gl, false); } - public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) { - } - public static void main(String[] args) throws IOException, MalformedURLException { int width = 640; int height = 600; @@ -520,42 +602,60 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener { boolean forceES3 = false; boolean forceGL3 = false; boolean forceGLDef = false; + int vid = GLMediaPlayer.STREAM_ID_AUTO; + int aid = GLMediaPlayer.STREAM_ID_AUTO; + final boolean origSize; - String url_s="http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4"; - for(int i=0; i<args.length; i++) { - if(args[i].equals("-width")) { - i++; - width = MiscUtils.atoi(args[i], width); - } else if(args[i].equals("-height")) { - i++; - height = MiscUtils.atoi(args[i], height); - } else if(args[i].equals("-textureCount")) { - i++; - textureCount = MiscUtils.atoi(args[i], textureCount); - } else if(args[i].equals("-es2")) { - forceES2 = true; - } else if(args[i].equals("-es3")) { - forceES3 = true; - } else if(args[i].equals("-gl3")) { - forceGL3 = true; - } else if(args[i].equals("-gldef")) { - forceGLDef = true; - } else if(args[i].equals("-projection")) { - ortho=false; - } else if(args[i].equals("-zoom")) { - zoom=true; - } else if(args[i].equals("-url")) { - i++; - url_s = args[i]; + String url_s="http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4"; + { + boolean _origSize = false; + for(int i=0; i<args.length; i++) { + if(args[i].equals("-vid")) { + i++; + vid = MiscUtils.atoi(args[i], vid); + } else if(args[i].equals("-aid")) { + i++; + aid = MiscUtils.atoi(args[i], aid); + } else if(args[i].equals("-width")) { + i++; + width = MiscUtils.atoi(args[i], width); + } else if(args[i].equals("-height")) { + i++; + height = MiscUtils.atoi(args[i], height); + } else if(args[i].equals("-osize")) { + _origSize = true; + } else if(args[i].equals("-textureCount")) { + i++; + textureCount = MiscUtils.atoi(args[i], textureCount); + } else if(args[i].equals("-es2")) { + forceES2 = true; + } else if(args[i].equals("-es3")) { + forceES3 = true; + } else if(args[i].equals("-gl3")) { + forceGL3 = true; + } else if(args[i].equals("-gldef")) { + forceGLDef = true; + } else if(args[i].equals("-projection")) { + ortho=false; + } else if(args[i].equals("-zoom")) { + zoom=true; + } else if(args[i].equals("-url")) { + i++; + url_s = args[i]; + } else if(args[i].equals("-wait")) { + waitForKey = true; + } } + origSize = _origSize; } + System.err.println("vid "+vid+", aid "+aid); System.err.println("textureCount "+textureCount); System.err.println("forceES2 "+forceES2); System.err.println("forceES3 "+forceES3); System.err.println("forceGL3 "+forceGL3); System.err.println("forceGLDef "+forceGLDef); - final MovieSimple ms = new MovieSimple(new URL(url_s).openConnection()); + final MovieSimple ms = new MovieSimple(new URL(url_s).openConnection(), vid, aid); ms.setTextureCount(textureCount); ms.setScaleOrig(!zoom); ms.setOrthoProjection(ortho); @@ -575,9 +675,21 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener { } System.err.println("GLProfile: "+glp); GLCapabilities caps = new GLCapabilities(glp); - GLWindow window = GLWindow.create(caps); + final GLWindow window = GLWindow.create(caps); window.addGLEventListener(ms); + ms.mPlayer.addEventListener(new GLMediaEventListener() { + @Override + public void newFrameAvailable(GLMediaPlayer ts, TextureFrame newFrame, long when) { + } + + @Override + public void attributesChanges(final GLMediaPlayer mp, int event_mask, long when) { + if( 0 != ( GLMediaEventListener.EVENT_CHANGE_SIZE & event_mask ) && origSize ) { + window.setSize(mp.getWidth(), mp.getHeight()); + } + } + }); window.setSize(width, height); window.setVisible(true); |