aboutsummaryrefslogtreecommitdiffstats
path: root/src/test/com
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2013-08-14 07:02:59 +0200
committerSven Gothel <[email protected]>2013-08-14 07:02:59 +0200
commitc37629ea8fdcb11f7f8a18e37a4cde57d4ba6a01 (patch)
tree96e6ef2b8db44f3dd331ac78a0a52d5d5ea15e50 /src/test/com
parentbc3776633ccad81199a96ff8116195133d862395 (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/com')
-rw-r--r--src/test/com/jogamp/opengl/test/android/MovieCubeActivity0.java3
-rw-r--r--src/test/com/jogamp/opengl/test/android/MovieSimpleActivity0.java3
-rw-r--r--src/test/com/jogamp/opengl/test/android/MovieSimpleActivity1.java4
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureSequenceCubeES2.java23
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java157
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java228
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);