summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/demos/com/jogamp/opengl/demos/android/MovieCubeActivity0a.java2
-rw-r--r--src/demos/com/jogamp/opengl/demos/android/MovieCubeActivity0b.java2
-rw-r--r--src/demos/com/jogamp/opengl/demos/android/MovieSimpleActivity0.java2
-rw-r--r--src/demos/com/jogamp/opengl/demos/android/MovieSimpleActivity1.java4
-rw-r--r--src/demos/com/jogamp/opengl/demos/av/CrossFadePlayer.java6
-rw-r--r--src/demos/com/jogamp/opengl/demos/av/MovieCube.java102
-rw-r--r--src/demos/com/jogamp/opengl/demos/av/MovieSBSStereo.java14
-rw-r--r--src/demos/com/jogamp/opengl/demos/av/MovieSimple.java436
-rw-r--r--src/demos/com/jogamp/opengl/demos/es2/TextureSequenceCubeES2.java10
-rw-r--r--src/demos/com/jogamp/opengl/demos/es2/TextureSequenceES2.java373
-rw-r--r--src/demos/com/jogamp/opengl/demos/graph/TextRendererGLELBase.java51
-rw-r--r--src/demos/com/jogamp/opengl/demos/graph/ui/GPUUISceneGLListener0A.java14
-rw-r--r--src/demos/com/jogamp/opengl/demos/graph/ui/GPUUISceneTextAnim01.java32
-rw-r--r--src/graphui/classes/com/jogamp/graph/ui/gl/shapes/MediaButton.java4
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java45
-rw-r--r--src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java10
-rw-r--r--src/jogl/classes/jogamp/opengl/openal/av/ALAudioSink.java1
-rw-r--r--src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java206
-rw-r--r--src/jogl/classes/jogamp/opengl/util/av/NullGLMediaPlayer.java8
-rw-r--r--src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java35
-rw-r--r--src/jogl/classes/jogamp/opengl/util/av/impl/OMXGLMediaPlayer.java10
-rw-r--r--src/jogl/native/libav/ffmpeg_impl_template.c21
-rw-r--r--src/jogl/native/libav/ffmpeg_tool.h2
23 files changed, 820 insertions, 570 deletions
diff --git a/src/demos/com/jogamp/opengl/demos/android/MovieCubeActivity0a.java b/src/demos/com/jogamp/opengl/demos/android/MovieCubeActivity0a.java
index cdbaa7872..dfd0c94dc 100644
--- a/src/demos/com/jogamp/opengl/demos/android/MovieCubeActivity0a.java
+++ b/src/demos/com/jogamp/opengl/demos/android/MovieCubeActivity0a.java
@@ -125,7 +125,7 @@ public class MovieCubeActivity0a extends NewtBaseActivity {
}
}
});
- demoMain.initStream(streamLoc, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, 0);
+ demoMain.playStream(streamLoc, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, 0);
} catch (final IOException e) {
e.printStackTrace();
}
diff --git a/src/demos/com/jogamp/opengl/demos/android/MovieCubeActivity0b.java b/src/demos/com/jogamp/opengl/demos/android/MovieCubeActivity0b.java
index b04487b5f..649739e09 100644
--- a/src/demos/com/jogamp/opengl/demos/android/MovieCubeActivity0b.java
+++ b/src/demos/com/jogamp/opengl/demos/android/MovieCubeActivity0b.java
@@ -127,7 +127,7 @@ public class MovieCubeActivity0b extends NewtBaseActivity {
}
}
});
- demoMain.initStream(streamLoc, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, 0);
+ demoMain.playStream(streamLoc, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, 0);
} catch (final IOException e) {
e.printStackTrace();
}
diff --git a/src/demos/com/jogamp/opengl/demos/android/MovieSimpleActivity0.java b/src/demos/com/jogamp/opengl/demos/android/MovieSimpleActivity0.java
index 07d0b9914..4b051a8cd 100644
--- a/src/demos/com/jogamp/opengl/demos/android/MovieSimpleActivity0.java
+++ b/src/demos/com/jogamp/opengl/demos/android/MovieSimpleActivity0.java
@@ -121,7 +121,7 @@ public class MovieSimpleActivity0 extends NewtBaseActivity {
}
}
});
- demoMain.initStream(streamLoc, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, 0);
+ demoMain.playStream(streamLoc, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, 0);
scrn.removeReference();
diff --git a/src/demos/com/jogamp/opengl/demos/android/MovieSimpleActivity1.java b/src/demos/com/jogamp/opengl/demos/android/MovieSimpleActivity1.java
index d7a2aeae1..64a3c7c69 100644
--- a/src/demos/com/jogamp/opengl/demos/android/MovieSimpleActivity1.java
+++ b/src/demos/com/jogamp/opengl/demos/android/MovieSimpleActivity1.java
@@ -158,7 +158,7 @@ public class MovieSimpleActivity1 extends NewtBaseActivity {
}
}
});
- demoMain.initStream(streamLoc0, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, 0);
+ demoMain.playStream(streamLoc0, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, 0);
if(mPlayerHUD) {
final GLMediaPlayer mPlayerShared = mPlayerSharedHUD ? mPlayerMain : null;
@@ -205,7 +205,7 @@ public class MovieSimpleActivity1 extends NewtBaseActivity {
}
}
});
- demoHUD.initStream(streamLoc1, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, 0);
+ demoHUD.playStream(streamLoc1, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, 0);
glWindowHUD.setPosition(windowBounds.getX(), windowBounds.getY());
glWindowHUD.setSize(windowBounds.getWidth(), windowBounds.getHeight());
diff --git a/src/demos/com/jogamp/opengl/demos/av/CrossFadePlayer.java b/src/demos/com/jogamp/opengl/demos/av/CrossFadePlayer.java
index a4d5e73de..0e028279c 100644
--- a/src/demos/com/jogamp/opengl/demos/av/CrossFadePlayer.java
+++ b/src/demos/com/jogamp/opengl/demos/av/CrossFadePlayer.java
@@ -79,7 +79,7 @@ public class CrossFadePlayer
try {
mp.initGL(null);
if ( GLMediaPlayer.State.Paused == mp.getState() ) { // init OK
- mp.play();
+ mp.resume();
}
} catch (final Exception e) {
e.printStackTrace();
@@ -103,7 +103,7 @@ public class CrossFadePlayer
public void run() {
System.out.println("mp.setPlaySpeed(1f) returned: " + mp.setPlaySpeed(1f));
mp.seek(0);
- mp.play();
+ mp.resume();
}
}.start();
}
@@ -145,7 +145,7 @@ public class CrossFadePlayer
final Uri uri = Uri.valueOf(file);
System.out.println("State of player "+ i +": " + player[i].getState().toString());
System.out.println("...initializing stream "+ i +"...");
- player[i].initStream(uri, GLMediaPlayer.STREAM_ID_NONE, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.TEXTURE_COUNT_DEFAULT);
+ player[i].playStream(uri, GLMediaPlayer.STREAM_ID_NONE, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.TEXTURE_COUNT_DEFAULT);
}
}
diff --git a/src/demos/com/jogamp/opengl/demos/av/MovieCube.java b/src/demos/com/jogamp/opengl/demos/av/MovieCube.java
index caf2f9381..33e04d05b 100644
--- a/src/demos/com/jogamp/opengl/demos/av/MovieCube.java
+++ b/src/demos/com/jogamp/opengl/demos/av/MovieCube.java
@@ -98,7 +98,7 @@ public class MovieCube implements GLEventListener {
}
/**
- * Default constructor which also issues {@link #initStream(URI, int, int, int)} w/ default values
+ * Default constructor which also issues {@link #playStream(URI, int, int, int)} w/ default values
* and polls until the {@link GLMediaPlayer} is {@link GLMediaPlayer.State#Initialized}.
* If {@link GLMediaEventListener#EVENT_CHANGE_EOS} is reached, the stream is started over again.
* <p>
@@ -125,27 +125,16 @@ public class MovieCube implements GLEventListener {
public void run() {
// loop for-ever ..
mPlayer.seek(0);
- mPlayer.play();
+ mPlayer.resume();
} }.start();
}
}
});
- initStream(defURI, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.TEXTURE_COUNT_DEFAULT);
- StreamException se = null;
- while( null == se && GLMediaPlayer.State.Initialized != mPlayer.getState() ) {
- try {
- Thread.sleep(16);
- } catch (final InterruptedException e) { }
- se = mPlayer.getStreamException();
- }
- if( null != se ) {
- se.printStackTrace();
- throw new RuntimeException(se);
- }
+ playStream(defURI, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.TEXTURE_COUNT_DEFAULT);
}
/**
- * Custom constructor, user needs to issue {@link #initStream(URI, int, int, int)} afterwards.
+ * Custom constructor, user needs to issue {@link #playStream(URI, int, int, int)} afterwards.
*/
public MovieCube(final float zoom0, final float rotx, final float roty, final boolean showText) throws IOException {
this.zoom0 = zoom0;
@@ -156,8 +145,8 @@ public class MovieCube implements GLEventListener {
mPlayer = GLMediaPlayerFactory.createDefault();
}
- public void initStream(final Uri streamLoc, final int vid, final int aid, final int textureCount) {
- mPlayer.initStream(streamLoc, vid, aid, textureCount);
+ public void playStream(final Uri streamLoc, final int vid, final int aid, final int textureCount) {
+ mPlayer.playStream(streamLoc, vid, aid, textureCount);
System.out.println("pC.1b "+mPlayer);
}
@@ -179,16 +168,12 @@ public class MovieCube implements GLEventListener {
private final GLRegion regionFPS;
private float pixelSize1, pixelSize2, underlineSize;
- InfoTextRendererGLELBase(final GLProfile glp, final int rmode, final boolean lowPerfDevice) {
+ InfoTextRendererGLELBase(final GLProfile glp, final int rmode) {
// FIXME: Graph TextRenderer does not AA well w/o MSAA and FBO
super(rmode, MovieCube.this.textSampleCount);
this.setRendererCallbacks(RegionRenderer.defaultBlendEnable, RegionRenderer.defaultBlendDisable);
- if( lowPerfDevice ) {
- regionFPS = null;
- } else {
- regionFPS = GLRegion.create(glp, renderModes, null);
- System.err.println("RegionFPS "+Region.getRenderModeString(renderModes)+", sampleCount "+textSampleCount[0]+", class "+regionFPS.getClass().getName());
- }
+ regionFPS = GLRegion.create(glp, renderModes, null);
+ System.err.println("RegionFPS "+Region.getRenderModeString(renderModes)+", sampleCount "+textSampleCount[0]+", class "+regionFPS.getClass().getName());
staticRGBAColor[0] = 0.1f;
staticRGBAColor[1] = 0.1f;
staticRGBAColor[2] = 0.1f;
@@ -224,6 +209,8 @@ public class MovieCube implements GLEventListener {
super.dispose(drawable);
}
+ String text1_old = null;
+
@Override
public void display(final GLAutoDrawable drawable) {
final GLAnimatorControl anim = drawable.getAnimator();
@@ -251,12 +238,12 @@ public class MovieCube implements GLEventListener {
"; underlineSize "+underlineSize+" "+(pixelScale*underlineSize)+
"; yoff "+yoff1+", yoff2 "+yoff2); */
- final GL gl = drawable.getGL();
+ final GL2ES2 gl = drawable.getGL().getGL2ES2();
final String ptsPrec = null != regionFPS ? "3.1" : "3.0";
- final String text1 = String.format("%0"+ptsPrec+"f/%0"+ptsPrec+"f s, %s (%01.2fx, vol %01.2f), a %01.2f, fps %02.1f -> %02.1f / %02.1f, v-sync %d",
+ final String text1 = String.format("%0"+ptsPrec+"f/%0"+ptsPrec+"f s, %s (%01.2fx, vol %01.2f), a %01.2f, fps %02.1f -> %02.1f / %02.1f, swap %d",
pts, mPlayer.getDuration() / 1000f,
mPlayer.getState().toString().toLowerCase(), mPlayer.getPlaySpeed(), mPlayer.getAudioVolume(),
- aspect, mPlayer.getFramerate(), lfps, tfps, swapInterval);
+ aspect, mPlayer.getFramerate(), lfps, tfps, drawable.getGL().getSwapInterval());
final String text2 = String.format("audio: id %d, kbps %d, codec %s",
mPlayer.getAID(), mPlayer.getAudioBitrate()/1000, mPlayer.getAudioCodec());
final String text3 = String.format("video: id %d, kbps %d, codec %s",
@@ -264,10 +251,11 @@ public class MovieCube implements GLEventListener {
final String text4 = mPlayer.getUri().path.decode();
if( displayOSD && null != renderer ) {
gl.glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
- if( null != regionFPS ) {
- renderString(drawable, font, pixelSize1, text1, 1 /* col */, -1 /* row */, -1+z_diff, yoff1, 1f+z_diff, regionFPS.clear(gl.getGL2ES2())); // no-cache
+ if( !text1.equals(text1_old) ) {
+ renderString(drawable, font, pixelSize1, text1, 1 /* col */, -1 /* row */, -1+z_diff, yoff1, 1f+z_diff, regionFPS.clear(gl)); // clear-cache
+ text1_old = text1;
} else {
- renderString(drawable, font, pixelSize1, text1, 1 /* col */, -1 /* row */, -1+z_diff, yoff1, 1f+z_diff, true);
+ renderRegion(drawable, font, pixelSize1, 1 /* col */, -1 /* row */, -1+z_diff, yoff1, 1f+z_diff, regionFPS);
}
renderString(drawable, font, pixelSize2, text2, 1 /* col */, 0 /* row */, -1+z_diff, yoff2, 1f+z_diff, true);
renderString(drawable, font, pixelSize2, text3, 1 /* col */, 1 /* row */, -1+z_diff, yoff2, 1f+z_diff, true);
@@ -337,8 +325,12 @@ public class MovieCube implements GLEventListener {
break;
}
case KeyEvent.VK_SPACE: {
- if(GLMediaPlayer.State.Paused == mPlayer.getState()) {
- mPlayer.play();
+ if( GLMediaPlayer.State.Paused == mPlayer.getState() ) {
+ mPlayer.resume();
+ } else if(GLMediaPlayer.State.Uninitialized == mPlayer.getState()) {
+ playStream(mPlayer.getUri(), GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, 3 /* textureCount */);
+ } else if( e.isShiftDown() ) {
+ mPlayer.stop();
} else {
mPlayer.pause(false);
}
@@ -392,12 +384,7 @@ public class MovieCube implements GLEventListener {
if(null == mPlayer) {
throw new InternalError("mPlayer null");
}
- if( GLMediaPlayer.State.Uninitialized == mPlayer.getState() ) {
- throw new IllegalStateException("mPlayer in uninitialized state: "+mPlayer);
- }
- if( GLMediaPlayer.STREAM_ID_NONE == mPlayer.getVID() ) {
- // throw new IllegalStateException("mPlayer has no VID/stream selected: "+mPlayer);
- }
+ // final boolean hasVideo = GLMediaPlayer.STREAM_ID_NONE != mPlayer.getVID();
resetGLState = false;
final GL2ES2 gl = drawable.getGL().getGL2ES2();
@@ -409,20 +396,18 @@ public class MovieCube implements GLEventListener {
JunitTracer.waitForKey("Init>");
}
- if( GLMediaPlayer.State.Initialized == mPlayer.getState() ) {
- try {
- mPlayer.initGL(gl);
- } catch (final Exception e) {
- e.printStackTrace();
- if(null != mPlayer) {
- mPlayer.destroy(gl);
- mPlayer = null;
- }
- throw new GLException(e);
+ try {
+ mPlayer.initGL(gl);
+ } catch (final Exception e) {
+ e.printStackTrace();
+ if(null != mPlayer) {
+ mPlayer.destroy(gl);
+ mPlayer = null;
}
+ throw new GLException(e);
}
cube.init(drawable);
- mPlayer.play();
+ mPlayer.resume();
System.out.println("play.0 "+mPlayer);
boolean added;
@@ -436,8 +421,7 @@ public class MovieCube implements GLEventListener {
if( showText ) {
final int rmode = drawable.getChosenGLCapabilities().getSampleBuffers() ? 0 : Region.VBAA_RENDERING_BIT;
- final boolean lowPerfDevice = gl.isGLES();
- textRendererGLEL = new InfoTextRendererGLELBase(gl.getGLProfile(), rmode, lowPerfDevice);
+ textRendererGLEL = new InfoTextRendererGLELBase(gl.getGLProfile(), rmode);
drawable.addGLEventListener(textRendererGLEL);
}
}
@@ -451,10 +435,6 @@ public class MovieCube implements GLEventListener {
@Override
public void dispose(final GLAutoDrawable drawable) {
System.err.println(Thread.currentThread()+" MovieCube.dispose ... ");
- if( null != textRendererGLEL ) {
- drawable.disposeGLEventListener(textRendererGLEL, true);
- textRendererGLEL = null;
- }
disposeImpl(drawable, true);
}
@@ -466,6 +446,10 @@ public class MovieCube implements GLEventListener {
window.removeKeyListener(keyAction);
}
final GL2ES2 gl = drawable.getGL().getGL2ES2();
+ if( null != textRendererGLEL ) {
+ drawable.disposeGLEventListener(textRendererGLEL, true);
+ textRendererGLEL = null;
+ }
if( disposePlayer ) {
mPlayer.destroy(gl);
mPlayer=null;
@@ -498,7 +482,7 @@ public class MovieCube implements GLEventListener {
final long currentPos = System.currentTimeMillis();
if( currentPos - lastPerfPos > 2000 ) {
- System.err.println( mPlayer.getPerfString() );
+ // System.err.println( mPlayer.getPerfString() );
lastPerfPos = currentPos;
}
cube.display(drawable);
@@ -607,6 +591,7 @@ public class MovieCube implements GLEventListener {
anim.stop();
}
});
+ window.addGLEventListener(mc);
window.setSize(width, height);
window.setVisible(true);
System.err.println("Chosen: "+window.getChosenGLCapabilities());
@@ -626,12 +611,11 @@ public class MovieCube implements GLEventListener {
window.setSurfaceSize(mp.getWidth(), mp.getHeight());
}
// window.disposeGLEventListener(ms, false /* remove */ );
- mc.resetGLState();
}
if( 0 != ( GLMediaEventListener.EVENT_CHANGE_INIT & event_mask ) ) {
- window.addGLEventListener(mc);
anim.setUpdateFPSFrames(60, null);
anim.resetFPSCounter();
+ mc.resetGLState();
}
if( 0 != ( GLMediaEventListener.EVENT_CHANGE_PLAY & event_mask ) ) {
anim.resetFPSCounter();
@@ -649,7 +633,7 @@ public class MovieCube implements GLEventListener {
}
}
});
- mc.initStream(streamLoc, vid, aid, textureCount);
+ mc.playStream(streamLoc, vid, aid, textureCount);
}
}
diff --git a/src/demos/com/jogamp/opengl/demos/av/MovieSBSStereo.java b/src/demos/com/jogamp/opengl/demos/av/MovieSBSStereo.java
index 62e3975dd..519a51a87 100644
--- a/src/demos/com/jogamp/opengl/demos/av/MovieSBSStereo.java
+++ b/src/demos/com/jogamp/opengl/demos/av/MovieSBSStereo.java
@@ -218,7 +218,7 @@ public class MovieSBSStereo implements StereoGLEventListener {
if(GLMediaPlayer.State.Playing == mPlayer.getState()) {
mPlayer.pause(false);
} else {
- mPlayer.play();
+ mPlayer.resume();
}
}
}
@@ -245,7 +245,7 @@ public class MovieSBSStereo implements StereoGLEventListener {
final int pts0 = GLMediaPlayer.STREAM_ID_NONE != mPlayer.getVID() ? mPlayer.getVideoPTS() : mPlayer.getAudioPTS();
mPlayer.seek(pts0 + (int) (mPlayer.getDuration() * dp));
} else {
- mPlayer.play();
+ mPlayer.resume();
rotate = 1;
zoom = zoom1;
}
@@ -286,7 +286,7 @@ public class MovieSBSStereo implements StereoGLEventListener {
}
case KeyEvent.VK_SPACE: {
if(GLMediaPlayer.State.Paused == mPlayer.getState()) {
- mPlayer.play();
+ mPlayer.resume();
} else {
mPlayer.pause(false);
}
@@ -329,7 +329,7 @@ public class MovieSBSStereo implements StereoGLEventListener {
}
} };
- /** user needs to issue {@link #initStream(URI, int, int, int)} afterwards. */
+ /** user needs to issue {@link #playStream(URI, int, int, int)} afterwards. */
public MovieSBSStereo() throws IllegalStateException {
mPlayerScaleOrig = false;
mPlayer = GLMediaPlayerFactory.createDefault();
@@ -338,7 +338,7 @@ public class MovieSBSStereo implements StereoGLEventListener {
}
public void initStream(final Uri streamLoc, final int vid, final int aid, final int textureCount) {
- mPlayer.initStream(streamLoc, vid, aid, textureCount);
+ mPlayer.playStream(streamLoc, vid, aid, textureCount);
System.out.println("pC.1b "+mPlayer);
}
@@ -531,7 +531,7 @@ public class MovieSBSStereo implements StereoGLEventListener {
System.out.println(st);
}
- mPlayer.play();
+ mPlayer.resume();
System.out.println("play.0 "+mPlayer);
startTime = System.currentTimeMillis();
@@ -861,7 +861,7 @@ public class MovieSBSStereo implements StereoGLEventListener {
public void run() {
mp.setPlaySpeed(1f);
mp.seek(0);
- mp.play();
+ mp.resume();
}
}.start();
}
diff --git a/src/demos/com/jogamp/opengl/demos/av/MovieSimple.java b/src/demos/com/jogamp/opengl/demos/av/MovieSimple.java
index 42c7b94a5..27735f4c7 100644
--- a/src/demos/com/jogamp/opengl/demos/av/MovieSimple.java
+++ b/src/demos/com/jogamp/opengl/demos/av/MovieSimple.java
@@ -1,5 +1,5 @@
/**
- * Copyright 2012 JogAmp Community. All rights reserved.
+ * Copyright 2012-2023 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
@@ -32,10 +32,8 @@ import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
-import java.nio.FloatBuffer;
import com.jogamp.common.net.Uri;
-import com.jogamp.common.os.Platform;
import com.jogamp.common.util.InterruptSource;
import com.jogamp.graph.curve.Region;
import com.jogamp.graph.curve.opengl.GLRegion;
@@ -53,36 +51,25 @@ import com.jogamp.newt.event.MouseListener;
import com.jogamp.newt.event.WindowAdapter;
import com.jogamp.newt.event.WindowEvent;
import com.jogamp.newt.opengl.GLWindow;
-import com.jogamp.opengl.GL;
import com.jogamp.opengl.GL2ES2;
import com.jogamp.opengl.GLAnimatorControl;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLCapabilities;
-import com.jogamp.opengl.GLES2;
import com.jogamp.opengl.GLEventListener;
import com.jogamp.opengl.GLException;
-import com.jogamp.opengl.GLExtensions;
import com.jogamp.opengl.GLProfile;
import com.jogamp.opengl.GLRunnable;
-import com.jogamp.opengl.GLUniformData;
import com.jogamp.opengl.JoglVersion;
+import com.jogamp.opengl.demos.es2.TextureSequenceES2;
import com.jogamp.opengl.demos.graph.TextRendererGLELBase;
import com.jogamp.opengl.demos.util.MiscUtils;
-import com.jogamp.opengl.fixedfunc.GLMatrixFunc;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.util.GLArrayDataServer;
import com.jogamp.opengl.util.GLReadBufferUtil;
-import com.jogamp.opengl.util.PMVMatrix;
import com.jogamp.opengl.util.av.GLMediaPlayer;
import com.jogamp.opengl.util.av.GLMediaPlayer.GLMediaEventListener;
import com.jogamp.opengl.util.av.GLMediaPlayer.StreamException;
import com.jogamp.opengl.util.av.GLMediaPlayerFactory;
-import com.jogamp.opengl.util.glsl.ShaderCode;
-import com.jogamp.opengl.util.glsl.ShaderProgram;
-import com.jogamp.opengl.util.glsl.ShaderState;
-import com.jogamp.opengl.util.texture.Texture;
-import com.jogamp.opengl.util.texture.TextureCoords;
-import com.jogamp.opengl.util.texture.TextureSequence;
import com.jogamp.opengl.util.texture.TextureSequence.TextureFrame;
/**
@@ -99,9 +86,8 @@ public class MovieSimple implements GLEventListener {
private static boolean waitForKey = false;
private int surfWidth, surfHeight;
private int prevMouseX; // , prevMouseY;
- private int rotate = 0;
+ private final int rotate = 0;
private boolean orthoProjection = true;
- private float nearPlaneNormalized;
private float zoom0;
private float zoom1;
private float zoom;
@@ -111,21 +97,16 @@ public class MovieSimple implements GLEventListener {
private int swapInterval = 1;
private boolean swapIntervalSet = true;
+ private TextureSequenceES2 screen=null;
private GLMediaPlayer mPlayer;
private final boolean mPlayerShared;
private boolean mPlayerScaleOrig;
- private float[] verts = null;
+ private final float[] verts = null;
private GLArrayDataServer interleavedVBO;
private volatile boolean resetGLState = false;
private volatile GLAutoDrawable autoDrawable = null;
- private ShaderState st;
- private PMVMatrix pmvMatrix;
- private GLUniformData pmvMatrixUniform;
- private static final String shaderBasename = "texsequence_xxx";
- private static final String myTextureLookupName = "myTexture2D";
-
/** Blender's Big Buck Bunny: 24f 416p H.264, AAC 48000 Hz, 2 ch, mpeg stream. */
public static final Uri defURI;
static {
@@ -147,16 +128,12 @@ public class MovieSimple implements GLEventListener {
private final float fontSize = 10f;
private final GLRegion regionFPS;
- InfoTextRendererGLELBase(final GLProfile glp, final int rmode, final boolean lowPerfDevice) {
+ InfoTextRendererGLELBase(final GLProfile glp, final int rmode) {
// FIXME: Graph TextRenderer does not AA well w/o MSAA and FBO
super(rmode, textSampleCount);
this.setRendererCallbacks(RegionRenderer.defaultBlendEnable, RegionRenderer.defaultBlendDisable);
- if( lowPerfDevice ) {
- regionFPS = null;
- } else {
- regionFPS = GLRegion.create(glp, renderModes, null);
- System.err.println("RegionFPS "+Region.getRenderModeString(renderModes)+", sampleCount "+textSampleCount[0]+", class "+regionFPS.getClass().getName());
- }
+ regionFPS = GLRegion.create(glp, renderModes, null);
+ System.err.println("RegionFPS "+Region.getRenderModeString(renderModes)+", sampleCount "+textSampleCount[0]+", class "+regionFPS.getClass().getName());
staticRGBAColor[0] = 0.9f;
staticRGBAColor[1] = 0.9f;
staticRGBAColor[2] = 0.9f;
@@ -176,6 +153,8 @@ public class MovieSimple implements GLEventListener {
super.dispose(drawable);
}
+ String text1_old = null;
+
@Override
public void display(final GLAutoDrawable drawable) {
final GLAnimatorControl anim = drawable.getAnimator();
@@ -191,10 +170,10 @@ public class MovieSimple implements GLEventListener {
final float aspect = (float)mPlayer.getWidth() / (float)mPlayer.getHeight();
final String ptsPrec = null != regionFPS ? "3.1" : "3.0";
- final String text1 = String.format("%0"+ptsPrec+"f/%0"+ptsPrec+"f s, %s (%01.2fx, vol %01.2f), a %01.2f, fps %02.1f -> %02.1f / %02.1f, v-sync %b",
+ final String text1 = String.format("%0"+ptsPrec+"f/%0"+ptsPrec+"f s, %s (%01.2fx, vol %01.2f), a %01.2f, fps %02.1f -> %02.1f / %02.1f, swap %d",
pts, mPlayer.getDuration() / 1000f,
mPlayer.getState().toString().toLowerCase(), mPlayer.getPlaySpeed(), mPlayer.getAudioVolume(),
- aspect, mPlayer.getFramerate(), lfps, tfps, swapIntervalSet);
+ aspect, mPlayer.getFramerate(), lfps, tfps, drawable.getGL().getSwapInterval());
final String text2 = String.format("audio: id %d, kbps %d, codec %s",
mPlayer.getAID(), mPlayer.getAudioBitrate()/1000, mPlayer.getAudioCodec());
final String text3 = String.format("video: id %d, kbps %d, codec %s",
@@ -203,11 +182,12 @@ public class MovieSimple implements GLEventListener {
if( displayOSD && null != renderer ) {
// We share ClearColor w/ MovieSimple's init !
final float pixelSize = FontScale.toPixels(fontSize, dpiH);
- if( null != regionFPS ) {
- final GL2ES2 gl = drawable.getGL().getGL2ES2();
- renderString(drawable, font, pixelSize, text1, 1 /* col */, 1 /* row */, 0, 0, -1, regionFPS.clear(gl)); // no-cache
+ final GL2ES2 gl = drawable.getGL().getGL2ES2();
+ if( !text1.equals(text1_old) ) {
+ renderString(drawable, font, pixelSize, text1, 1 /* col */, 1 /* row */, 0, 0, -1, regionFPS.clear(gl)); // clear-cache
+ text1_old = text1;
} else {
- renderString(drawable, font, pixelSize, text1, 1 /* col */, 1 /* row */, 0, 0, -1, true);
+ renderRegion(drawable, font, pixelSize, 1 /* col */, 1 /* row */, 0, 0, -1, regionFPS);
}
renderString(drawable, font, pixelSize, text2, 1 /* col */, -4 /* row */, 0, height, -1, true);
renderString(drawable, font, pixelSize, text3, 1 /* col */, -3 /* row */, 0, height, -1, true);
@@ -249,15 +229,18 @@ public class MovieSimple implements GLEventListener {
if(GLMediaPlayer.State.Playing == mPlayer.getState()) {
mPlayer.pause(false);
} else {
- mPlayer.play();
+ mPlayer.resume();
}
}
}
@Override
public void mouseReleased(final MouseEvent e) {
if(e.getY()<=surfHeight/2) {
- rotate = -1;
zoom = zoom0;
+ if( null != screen ) {
+ screen.setZoom(zoom);
+ screen.setZRotation(-1f);
+ }
System.err.println("zoom: "+zoom);
}
}
@@ -276,9 +259,12 @@ public class MovieSimple implements GLEventListener {
final int pts0 = GLMediaPlayer.STREAM_ID_NONE != mPlayer.getVID() ? mPlayer.getVideoPTS() : mPlayer.getAudioPTS();
mPlayer.seek(pts0 + (int) (mPlayer.getDuration() * dp));
} else {
- mPlayer.play();
- rotate = 1;
+ mPlayer.resume();
zoom = zoom1;
+ if( null != screen ) {
+ screen.setZoom(zoom);
+ screen.setZRotation(1f);
+ }
}
prevMouseX = x;
@@ -288,6 +274,9 @@ public class MovieSimple implements GLEventListener {
public void mouseWheelMoved(final MouseEvent e) {
if( !e.isShiftDown() ) {
zoom += e.getRotation()[1]/10f; // vertical: wheel
+ if( null != screen ) {
+ screen.setZoom(zoom);
+ }
System.err.println("zoom: "+zoom);
}
} };
@@ -326,8 +315,12 @@ public class MovieSimple implements GLEventListener {
break;
}
case KeyEvent.VK_SPACE: {
- if(GLMediaPlayer.State.Paused == mPlayer.getState()) {
- mPlayer.play();
+ if( GLMediaPlayer.State.Paused == mPlayer.getState() ) {
+ mPlayer.resume();
+ } else if(GLMediaPlayer.State.Uninitialized == mPlayer.getState()) {
+ playStream(mPlayer.getUri(), GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, 3 /* textureCount */);
+ } else if( e.isShiftDown() ) {
+ mPlayer.stop();
} else {
mPlayer.pause(false);
}
@@ -376,7 +369,7 @@ public class MovieSimple implements GLEventListener {
} };
/**
- * Default constructor which also issues {@link #initStream(URI, int, int, int)} w/ default values
+ * Default constructor which also issues {@link #playStream(URI, int, int, int)} w/ default values
* and polls until the {@link GLMediaPlayer} is {@link GLMediaPlayer.State#Initialized}.
* If {@link GLMediaEventListener#EVENT_CHANGE_EOS} is reached, the stream is started over again.
* <p>
@@ -394,35 +387,21 @@ public class MovieSimple implements GLEventListener {
public void attributesChanged(final GLMediaPlayer mp, final int event_mask, final long when) {
System.err.println("MovieCube AttributesChanges: events_mask 0x"+Integer.toHexString(event_mask)+", when "+when);
System.err.println("MovieCube State: "+mp);
- if( 0 != ( GLMediaEventListener.EVENT_CHANGE_SIZE & event_mask ) ) {
- resetGLState();
- }
if( 0 != ( GLMediaEventListener.EVENT_CHANGE_EOS & event_mask ) ) {
new InterruptSource.Thread() {
@Override
public void run() {
// loop for-ever ..
mPlayer.seek(0);
- mPlayer.play();
+ mPlayer.resume();
} }.start();
}
}
});
- initStream(defURI, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, 3 /* textureCount */);
- StreamException se = null;
- while( null == se && GLMediaPlayer.State.Initialized != mPlayer.getState() ) {
- try {
- Thread.sleep(16);
- } catch (final InterruptedException e) { }
- se = mPlayer.getStreamException();
- }
- if( null != se ) {
- se.printStackTrace();
- throw new RuntimeException(se);
- }
+ playStream(defURI, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, 3 /* textureCount */);
}
- /** Custom constructor, user needs to issue {@link #initStream(URI, int, int, int)} afterwards. */
+ /** Custom constructor, user needs to issue {@link #playStream(URI, int, int, int)} afterwards. */
public MovieSimple(final GLMediaPlayer sharedMediaPlayer) throws IllegalStateException {
screenshot = new GLReadBufferUtil(false, false);
mPlayer = sharedMediaPlayer;
@@ -435,8 +414,8 @@ public class MovieSimple implements GLEventListener {
System.out.println("pC.1a shared "+mPlayerShared+", "+mPlayer);
}
- public void initStream(final Uri streamLoc, final int vid, final int aid, final int textureCount) {
- mPlayer.initStream(streamLoc, vid, aid, textureCount);
+ public void playStream(final Uri streamLoc, final int vid, final int aid, final int textureCount) {
+ mPlayer.playStream(streamLoc, vid, aid, textureCount);
System.out.println("pC.1b "+mPlayer);
}
@@ -452,73 +431,19 @@ public class MovieSimple implements GLEventListener {
public void setOrthoProjection(final boolean v) { orthoProjection=v; }
public boolean getOrthoProjection() { return orthoProjection; }
- public boolean hasEffect(final int e) { return 0 != ( effects & e ) ; }
public void setEffects(final int e) { effects = e; };
- public void setTransparency(final float alpha) {
- this.effects |= EFFECT_TRANSPARENT;
- this.alpha = alpha;
- }
+ public void setTransparency(final float alpha) { this.alpha = alpha; }
public void resetGLState() {
resetGLState = true;
}
- private void initShader(final GL2ES2 gl) {
- // Create & Compile the shader objects
- final ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, MovieSimple.class,
- "../shader", "../shader/bin", shaderBasename, true);
- final ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, MovieSimple.class,
- "../shader", "../shader/bin", shaderBasename, true);
-
- boolean preludeGLSLVersion = true;
- if( GLES2.GL_TEXTURE_EXTERNAL_OES == mPlayer.getTextureTarget() ) {
- if( !gl.isExtensionAvailable(GLExtensions.OES_EGL_image_external) ) {
- throw new GLException(GLExtensions.OES_EGL_image_external+" requested but not available");
- }
- if( Platform.OSType.ANDROID == Platform.getOSType() && gl.isGLES3() ) {
- // Bug on Nexus 10, ES3 - Android 4.3, where
- // GL_OES_EGL_image_external extension directive leads to a failure _with_ '#version 300 es' !
- // P0003: Extension 'GL_OES_EGL_image_external' not supported
- preludeGLSLVersion = false;
- }
- }
- rsVp.defaultShaderCustomization(gl, preludeGLSLVersion, true);
-
- int rsFpPos = preludeGLSLVersion ? rsFp.addGLSLVersion(gl) : 0;
- rsFpPos = rsFp.insertShaderSource(0, rsFpPos, mPlayer.getRequiredExtensionsShaderStub());
- rsFp.addDefaultShaderPrecision(gl, rsFpPos);
-
- final String texLookupFuncName = mPlayer.getTextureLookupFunctionName(myTextureLookupName);
- rsFp.replaceInShaderSource(myTextureLookupName, texLookupFuncName);
-
- // Inject TextureSequence shader details
- final StringBuilder sFpIns = new StringBuilder();
- sFpIns.append("uniform ").append(mPlayer.getTextureSampler2DType()).append(" mgl_ActiveTexture;\n");
- sFpIns.append(mPlayer.getTextureLookupFragmentShaderImpl());
- rsFp.insertShaderSource(0, "TEXTURE-SEQUENCE-CODE-BEGIN", 0, sFpIns);
-
- // Create & Link the shader program
- final ShaderProgram sp = new ShaderProgram();
- sp.add(rsVp);
- sp.add(rsFp);
- if(!sp.link(gl, System.err)) {
- throw new GLException("Couldn't link program: "+sp);
- }
-
- // Let's manage all our states using ShaderState.
- st = new ShaderState();
- st.attachShaderProgram(gl, sp, false);
- }
-
@Override
public void init(final GLAutoDrawable drawable) {
if(null == mPlayer) {
throw new InternalError("mPlayer null");
}
- if( GLMediaPlayer.State.Uninitialized == mPlayer.getState() ) {
- throw new IllegalStateException("mPlayer in uninitialized state: "+mPlayer);
- }
- final boolean hasVideo = GLMediaPlayer.STREAM_ID_NONE != mPlayer.getVID();
+ // final boolean hasVideo = GLMediaPlayer.STREAM_ID_NONE != mPlayer.getVID();
resetGLState = false;
zoom0 = orthoProjection ? 0f : -2.5f;
@@ -532,118 +457,26 @@ public class MovieSimple implements GLEventListener {
System.err.println("Alpha: "+alpha+", opaque "+drawable.getChosenGLCapabilities().isBackgroundOpaque()+
", "+drawable.getClass().getName()+", "+drawable);
+ screen = new TextureSequenceES2(mPlayer, mPlayerShared, orthoProjection, zoom);
+ screen.setEffects(effects);
+ screen.setTransparency(alpha);
+
if(waitForKey) {
JunitTracer.waitForKey("Init>");
}
- final Texture tex;
+
try {
- System.out.println("p0 "+mPlayer+", shared "+mPlayerShared);
- if(!mPlayerShared && GLMediaPlayer.State.Initialized == mPlayer.getState() ) {
- mPlayer.initGL(gl);
- }
- System.out.println("p1 "+mPlayer+", shared "+mPlayerShared);
- final TextureFrame frame = mPlayer.getLastTexture();
- if( null != frame ) {
- if( !hasVideo ) {
- throw new InternalError("XXX: "+mPlayer);
- }
- tex = frame.getTexture();
- if( null == tex ) {
- throw new InternalError("XXX: "+mPlayer);
- }
- } else {
- tex = null;
- if( hasVideo ) {
- throw new InternalError("XXX: "+mPlayer);
- }
- }
- if(!mPlayerShared) {
- mPlayer.setTextureMinMagFilter( new int[] { GL.GL_NEAREST, GL.GL_LINEAR } );
- }
- } catch (final Exception glex) {
- glex.printStackTrace();
- if(!mPlayerShared && null != mPlayer) {
+ mPlayer.initGL(gl);
+ } catch (final Exception e) {
+ e.printStackTrace();
+ if(null != mPlayer) {
mPlayer.destroy(gl);
mPlayer = null;
}
- throw new GLException(glex);
+ throw new GLException(e);
}
+ screen.init(drawable);
- if( hasVideo ) {
- initShader(gl);
-
- // Push the 1st uniform down the path
- st.useProgram(gl, true);
-
- final int[] viewPort = new int[] { 0, 0, drawable.getSurfaceWidth(), drawable.getSurfaceHeight()};
- pmvMatrix = new PMVMatrix();
- reshapePMV(viewPort[2], viewPort[3]);
- pmvMatrixUniform = new GLUniformData("mgl_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf());
- if(!st.uniform(gl, pmvMatrixUniform)) {
- throw new GLException("Error setting PMVMatrix in shader: "+st);
- }
- if(!st.uniform(gl, new GLUniformData("mgl_ActiveTexture", mPlayer.getTextureUnit()))) {
- throw new GLException("Error setting mgl_ActiveTexture in shader: "+st);
- }
-
- final float dWidth = drawable.getSurfaceWidth();
- final float dHeight = drawable.getSurfaceHeight();
- final float mWidth = mPlayer.getWidth();
- final float mHeight = mPlayer.getHeight();
- final float mAspect = mWidth/mHeight;
- System.err.println("XXX0: mov aspect: "+mAspect);
- float xs, ys;
- if(orthoProjection) {
- if(mPlayerScaleOrig && mWidth < dWidth && mHeight < dHeight) {
- xs = mWidth/2f; ys = xs / mAspect;
- } else {
- xs = dWidth/2f; ys = xs / mAspect; // w>h
- }
- } else {
- if(mPlayerScaleOrig && mWidth < dWidth && mHeight < dHeight) {
- xs = mAspect * ( mWidth / dWidth ) ; ys = xs / mAspect ;
- } else {
- xs = mAspect; ys = 1f; // b>h
- }
- }
- verts = new float[] { -1f*xs, -1f*ys, 0f, // LB
- 1f*xs, 1f*ys, 0f // RT
- };
- {
- System.err.println("XXX0: pixel LB: "+verts[0]+", "+verts[1]+", "+verts[2]);
- System.err.println("XXX0: pixel RT: "+verts[3]+", "+verts[4]+", "+verts[5]);
- final float[] winLB = new float[3];
- final float[] winRT = new float[3];
- pmvMatrix.gluProject(verts[0], verts[1], verts[2], viewPort, 0, winLB, 0);
- pmvMatrix.gluProject(verts[3], verts[4], verts[5], viewPort, 0, winRT, 0);
- System.err.println("XXX0: win LB: "+winLB[0]+", "+winLB[1]+", "+winLB[2]);
- System.err.println("XXX0: win RT: "+winRT[0]+", "+winRT[1]+", "+winRT[2]);
- }
-
- interleavedVBO = GLArrayDataServer.createGLSLInterleaved(3+4+2, GL.GL_FLOAT, false, 3*4, GL.GL_STATIC_DRAW);
- {
- interleavedVBO.addGLSLSubArray("mgl_Vertex", 3, GL.GL_ARRAY_BUFFER);
- interleavedVBO.addGLSLSubArray("mgl_Color", 4, GL.GL_ARRAY_BUFFER);
- interleavedVBO.addGLSLSubArray("mgl_MultiTexCoord", 2, GL.GL_ARRAY_BUFFER);
- }
- updateInterleavedVBO(gl, tex);
-
- st.ownAttribute(interleavedVBO, true);
- gl.glClearColor(0.3f, 0.3f, 0.3f, 0.3f);
-
- gl.glEnable(GL.GL_DEPTH_TEST);
-
- st.useProgram(gl, false);
-
- // Let's show the completed shader state ..
- System.out.println("iVBO: "+interleavedVBO);
- System.out.println(st);
- }
-
- if(!mPlayerShared) {
- mPlayer.play();
- System.out.println("play.0 "+mPlayer);
- }
startTime = System.currentTimeMillis();
final Object upstreamWidget = drawable.getUpstreamWidget();
@@ -655,101 +488,22 @@ public class MovieSimple implements GLEventListener {
surfHeight = window.getSurfaceHeight();
}
final int rmode = drawable.getChosenGLCapabilities().getSampleBuffers() ? 0 : Region.VBAA_RENDERING_BIT;
- final boolean lowPerfDevice = gl.isGLES();
- textRendererGLEL = new InfoTextRendererGLELBase(gl.getGLProfile(), rmode, lowPerfDevice);
+ textRendererGLEL = new InfoTextRendererGLELBase(gl.getGLProfile(), rmode);
drawable.addGLEventListener(textRendererGLEL);
}
- protected void updateInterleavedVBO(final GL gl, final Texture tex) {
- final float ss = 1f, ts = 1f; // scale tex-coord
- final boolean wasEnabled = interleavedVBO.enabled();
- interleavedVBO.seal(gl, false);
- interleavedVBO.rewind();
- {
- final FloatBuffer ib = (FloatBuffer)interleavedVBO.getBuffer();
- final TextureCoords tc = tex.getImageTexCoords();
- System.err.println("XXX0: "+tc);
- System.err.println("XXX0: tex aspect: "+tex.getAspectRatio());
- System.err.println("XXX0: tex y-flip: "+tex.getMustFlipVertically());
-
- // left-bottom
- ib.put(verts[0]); ib.put(verts[1]); ib.put(verts[2]);
- if( hasEffect(EFFECT_GRADIENT_BOTTOM2TOP) ) {
- ib.put( 0); ib.put( 0); ib.put( 0); ib.put(alpha);
- } else {
- ib.put( 1); ib.put( 1); ib.put( 1); ib.put(alpha);
- }
- ib.put( tc.left() *ss); ib.put( tc.bottom() *ts);
-
- // right-bottom
- ib.put(verts[3]); ib.put(verts[1]); ib.put(verts[2]);
- if( hasEffect(EFFECT_GRADIENT_BOTTOM2TOP) ) {
- ib.put( 0); ib.put( 0); ib.put( 0); ib.put(alpha);
- } else {
- ib.put( 1); ib.put( 1); ib.put( 1); ib.put(alpha);
- }
- ib.put( tc.right() *ss); ib.put( tc.bottom() *ts);
-
- // left-top
- ib.put(verts[0]); ib.put(verts[4]); ib.put(verts[2]);
- ib.put( 1); ib.put( 1); ib.put( 1); ib.put(alpha);
- ib.put( tc.left() *ss); ib.put( tc.top() *ts);
-
- // right-top
- ib.put(verts[3]); ib.put(verts[4]); ib.put(verts[2]);
- ib.put( 1); ib.put( 1); ib.put( 1); ib.put(alpha);
- ib.put( tc.right() *ss); ib.put( tc.top() *ts);
- }
- interleavedVBO.seal(gl, true);
- if( !wasEnabled ) {
- interleavedVBO.enableBuffer(gl, false);
- }
- }
-
@Override
public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) {
- final GL2ES2 gl = drawable.getGL().getGL2ES2();
if(null == mPlayer) { return; }
+ screen.reshape(drawable, x, y, width, height);
surfWidth = width;
surfHeight = height;
-
- if(null != st) {
- reshapePMV(width, height);
- st.useProgram(gl, true);
- st.uniform(gl, pmvMatrixUniform);
- st.useProgram(gl, false);
- }
-
System.out.println("pR "+mPlayer);
}
- private final float zNear = 1f;
- private final float zFar = 10f;
-
- private void reshapePMV(final int width, final int height) {
- pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
- pmvMatrix.glLoadIdentity();
- if(orthoProjection) {
- final float fw = width / 2f;
- final float fh = height/ 2f;
- pmvMatrix.glOrthof(-fw, fw, -fh, fh, -1.0f, 1.0f);
- nearPlaneNormalized = 0f;
- } else {
- pmvMatrix.gluPerspective(45.0f, (float)width / (float)height, zNear, zFar);
- nearPlaneNormalized = 1f/(10f-1f);
- }
- System.err.println("XXX0: Perspective nearPlaneNormalized: "+nearPlaneNormalized);
-
- pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
- pmvMatrix.glLoadIdentity();
- pmvMatrix.glTranslatef(0, 0, zoom0);
- }
-
@Override
public void dispose(final GLAutoDrawable drawable) {
autoDrawable = null;
- drawable.disposeGLEventListener(textRendererGLEL, true);
- textRendererGLEL = null;
screenshot.dispose(drawable.getGL());
disposeImpl(drawable, true);
}
@@ -766,21 +520,21 @@ public class MovieSimple implements GLEventListener {
System.out.println("pD.1 "+mPlayer+", disposePlayer "+disposePlayer);
final GL2ES2 gl = drawable.getGL().getGL2ES2();
+ if( null != textRendererGLEL ) {
+ drawable.disposeGLEventListener(textRendererGLEL, true);
+ textRendererGLEL = null;
+ }
if( disposePlayer ) {
if(!mPlayerShared) {
mPlayer.destroy(gl);
+ } else {
+ // mPlayer.stop(gl);
}
System.out.println("pD.X "+mPlayer);
mPlayer=null;
}
- pmvMatrixUniform = null;
- if(null != pmvMatrix) {
- pmvMatrix=null;
- }
- if(null != st) {
- st.destroy(gl);
- st=null;
- }
+ screen.dispose(drawable);
+ screen = null;
}
long lastPerfPos = 0;
@@ -791,7 +545,9 @@ public class MovieSimple implements GLEventListener {
if( swapIntervalSet ) {
final int _swapInterval = swapInterval;
gl.setSwapInterval(_swapInterval); // in case switching the drawable (impl. may bound attribute there)
- drawable.getAnimator().resetFPSCounter();
+ if( null != drawable.getAnimator() ) {
+ drawable.getAnimator().resetFPSCounter();
+ }
swapInterval = gl.getSwapInterval();
System.err.println("Swap Interval: "+_swapInterval+" -> "+swapInterval);
swapIntervalSet = false;
@@ -808,50 +564,10 @@ public class MovieSimple implements GLEventListener {
final long currentPos = System.currentTimeMillis();
if( currentPos - lastPerfPos > 2000 ) {
- System.err.println( mPlayer.getPerfString() );
+ // System.err.println( mPlayer.getPerfString() );
lastPerfPos = currentPos;
}
-
- 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);
- pmvMatrix.glLoadIdentity();
- pmvMatrix.glTranslatef(0, 0, zoom);
- if(rotate > 0) {
- final float ang = ((System.currentTimeMillis() - startTime) * 360.0f) / 8000.0f;
- pmvMatrix.glRotatef(ang, 0, 0, 1);
- } else {
- rotate = 0;
- }
- st.uniform(gl, pmvMatrixUniform);
- interleavedVBO.enableBuffer(gl, true);
- Texture tex = null;
- if(null!=mPlayer) {
- final TextureSequence.TextureFrame texFrame;
- if( mPlayerShared ) {
- texFrame=mPlayer.getLastTexture();
- } else {
- texFrame=mPlayer.getNextTexture(gl);
- }
- if(null != texFrame) {
- tex = texFrame.getTexture();
- gl.glActiveTexture(GL.GL_TEXTURE0+mPlayer.getTextureUnit());
- tex.enable(gl);
- tex.bind(gl);
- }
- }
- gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, 4);
- if(null != tex) {
- tex.disable(gl);
- }
- interleavedVBO.enableBuffer(gl, false);
- st.useProgram(gl, false);
+ screen.display(drawable);
}
static class MyGLMediaEventListener implements GLMediaEventListener {
@@ -879,15 +595,16 @@ public class MovieSimple implements GLEventListener {
window.setSurfaceSize(mp.getWidth(), mp.getHeight());
}
// window.disposeGLEventListener(ms, false /* remove */ );
- ms.resetGLState();
+ // ms.resetGLState();
}
if( 0 != ( GLMediaEventListener.EVENT_CHANGE_INIT & event_mask ) ) {
System.err.println("MovieSimple State: INIT");
// Use GLEventListener in all cases [A+V, V, A]
- window.addGLEventListener(ms);
final GLAnimatorControl anim = window.getAnimator();
anim.setUpdateFPSFrames(60, null);
anim.resetFPSCounter();
+ ms.resetGLState();
+
/**
* Kick off player w/o GLEventListener, i.e. for audio only.
*
@@ -928,7 +645,7 @@ public class MovieSimple implements GLEventListener {
public void run() {
mp.setPlaySpeed(1f);
mp.seek(0);
- mp.play();
+ mp.resume();
}
}.start();
} else {
@@ -1100,10 +817,11 @@ public class MovieSimple implements GLEventListener {
mss[i].mPlayer.attachObject(WINDOW_KEY, windows[i]);
mss[i].mPlayer.addEventListener(myGLMediaEventListener);
+ anim.add(windows[i]);
+ windows[i].addGLEventListener(mss[i]);
windows[i].setTitle("Player "+i);
windows[i].setSize(width, height);
windows[i].setVisible(true);
- anim.add(windows[i]);
final Uri streamLocN;
if( 0 == i ) {
@@ -1116,7 +834,7 @@ public class MovieSimple implements GLEventListener {
}
}
System.err.println("Win #"+i+": stream "+streamLocN);
- mss[i].initStream(streamLocN, vid, aid, textureCount);
+ mss[i].playStream(streamLocN, vid, aid, textureCount);
}
}
diff --git a/src/demos/com/jogamp/opengl/demos/es2/TextureSequenceCubeES2.java b/src/demos/com/jogamp/opengl/demos/es2/TextureSequenceCubeES2.java
index 6a7115143..26a26e3e1 100644
--- a/src/demos/com/jogamp/opengl/demos/es2/TextureSequenceCubeES2.java
+++ b/src/demos/com/jogamp/opengl/demos/es2/TextureSequenceCubeES2.java
@@ -1,5 +1,5 @@
/**
- * Copyright 2012 JogAmp Community. All rights reserved.
+ * Copyright 2012-2023 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
@@ -45,7 +45,6 @@ import com.jogamp.newt.event.MouseAdapter;
import com.jogamp.newt.event.MouseEvent;
import com.jogamp.newt.event.MouseListener;
import com.jogamp.opengl.GLExtensions;
-import com.jogamp.opengl.JoglVersion;
import com.jogamp.opengl.util.GLArrayDataServer;
import com.jogamp.opengl.util.PMVMatrix;
import com.jogamp.opengl.util.glsl.ShaderCode;
@@ -84,12 +83,15 @@ public class TextureSequenceCubeES2 implements GLEventListener {
int ly = 0;
boolean first = false;
+ @Override
public void mousePressed(final MouseEvent e) {
first = true;
}
+ @Override
public void mouseMoved(final MouseEvent e) {
first = false;
}
+ @Override
public void mouseDragged(final MouseEvent e) {
int width, height;
final Object source = e.getSource();
@@ -143,6 +145,7 @@ public class TextureSequenceCubeES2 implements GLEventListener {
ly = ny;
}
}
+ @Override
public void mouseWheelMoved(final MouseEvent e) {
// System.err.println("XXX "+e);
if( !e.isShiftDown() ) {
@@ -206,9 +209,9 @@ public class TextureSequenceCubeES2 implements GLEventListener {
GLArrayDataServer interleavedVBO, cubeIndicesVBO;
+ @Override
public void init(final GLAutoDrawable drawable) {
final GL2ES2 gl = drawable.getGL().getGL2ES2();
- System.err.println(JoglVersion.getGLInfo(gl, null));
final TextureFrame frame = texSeq.getLastTexture();
if( null == frame ) {
return;
@@ -304,6 +307,7 @@ public class TextureSequenceCubeES2 implements GLEventListener {
System.out.println(st);
}
+ @Override
public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) {
final GL2ES2 gl = drawable.getGL().getGL2ES2();
diff --git a/src/demos/com/jogamp/opengl/demos/es2/TextureSequenceES2.java b/src/demos/com/jogamp/opengl/demos/es2/TextureSequenceES2.java
new file mode 100644
index 000000000..fd934cb1e
--- /dev/null
+++ b/src/demos/com/jogamp/opengl/demos/es2/TextureSequenceES2.java
@@ -0,0 +1,373 @@
+/**
+ * Copyright 2012-2023 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.demos.es2;
+
+import java.nio.FloatBuffer;
+
+import com.jogamp.common.os.Platform;
+import com.jogamp.opengl.GL;
+import com.jogamp.opengl.GL2ES2;
+import com.jogamp.opengl.GLAutoDrawable;
+import com.jogamp.opengl.GLES2;
+import com.jogamp.opengl.GLEventListener;
+import com.jogamp.opengl.GLException;
+import com.jogamp.opengl.GLExtensions;
+import com.jogamp.opengl.GLUniformData;
+import com.jogamp.opengl.fixedfunc.GLMatrixFunc;
+import com.jogamp.opengl.util.GLArrayDataServer;
+import com.jogamp.opengl.util.PMVMatrix;
+import com.jogamp.opengl.util.glsl.ShaderCode;
+import com.jogamp.opengl.util.glsl.ShaderProgram;
+import com.jogamp.opengl.util.glsl.ShaderState;
+import com.jogamp.opengl.util.texture.Texture;
+import com.jogamp.opengl.util.texture.TextureCoords;
+import com.jogamp.opengl.util.texture.TextureSequence;
+import com.jogamp.opengl.util.texture.TextureSequence.TextureFrame;
+
+/**
+ * Simple planar movie player w/ orthogonal 1:1 projection.
+ */
+public class TextureSequenceES2 implements GLEventListener {
+ public static final int EFFECT_NORMAL = 0;
+ public static final int EFFECT_GRADIENT_BOTTOM2TOP = 1<<1;
+ public static final int EFFECT_TRANSPARENT = 1<<3;
+
+ private TextureSequence texSeq;
+ private final boolean texSeqShared;
+ private ShaderState st;
+ private PMVMatrix pmvMatrix;
+ private GLUniformData pmvMatrixUniform;
+
+ private float zrot = 0f;
+ private final boolean orthoProjection;
+ private float nearPlaneNormalized;
+ private float zoom;
+
+ private int effects = EFFECT_NORMAL;
+ private float alpha = 1.0f;
+
+ private boolean mPlayerScaleOrig;
+ private float[] verts = null;
+ private GLArrayDataServer interleavedVBO;
+
+ public TextureSequenceES2(final TextureSequence texSource, final boolean texSeqShared, final boolean orthoProjection, final float zoom0) throws IllegalStateException {
+ this.texSeq = texSource;
+ this.texSeqShared = texSeqShared;
+ this.orthoProjection = orthoProjection;
+ this.zoom = zoom0;
+ }
+
+ public void setZoom(final float zoom) { this.zoom = zoom; }
+ public float getZoom() { return zoom; }
+ public void setZRotation(final float zrot) { this.zrot = zrot; }
+ public boolean hasEffect(final int e) { return 0 != ( effects & e ) ; }
+ public void setEffects(final int e) { effects = e; };
+ public void setTransparency(final float alpha) {
+ this.effects |= EFFECT_TRANSPARENT;
+ this.alpha = alpha;
+ }
+
+ private static final String shaderBasename = "texsequence_xxx";
+ private static final String myTextureLookupName = "myTexture2D";
+
+ private void initShader(final GL2ES2 gl) {
+ // Create & Compile the shader objects
+ final ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, this.getClass(),
+ "shader", "shader/bin", shaderBasename, true);
+ final ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, this.getClass(),
+ "shader", "shader/bin", shaderBasename, true);
+
+ boolean preludeGLSLVersion = true;
+ if( GLES2.GL_TEXTURE_EXTERNAL_OES == texSeq.getTextureTarget() ) {
+ if( !gl.isExtensionAvailable(GLExtensions.OES_EGL_image_external) ) {
+ throw new GLException(GLExtensions.OES_EGL_image_external+" requested but not available");
+ }
+ if( Platform.OSType.ANDROID == Platform.getOSType() && gl.isGLES3() ) {
+ // Bug on Nexus 10, ES3 - Android 4.3, where
+ // GL_OES_EGL_image_external extension directive leads to a failure _with_ '#version 300 es' !
+ // P0003: Extension 'GL_OES_EGL_image_external' not supported
+ preludeGLSLVersion = false;
+ }
+ }
+ rsVp.defaultShaderCustomization(gl, preludeGLSLVersion, true);
+
+ int rsFpPos = preludeGLSLVersion ? rsFp.addGLSLVersion(gl) : 0;
+ rsFpPos = rsFp.insertShaderSource(0, rsFpPos, texSeq.getRequiredExtensionsShaderStub());
+ rsFp.addDefaultShaderPrecision(gl, rsFpPos);
+
+ final String texLookupFuncName = texSeq.getTextureLookupFunctionName(myTextureLookupName);
+ rsFp.replaceInShaderSource(myTextureLookupName, texLookupFuncName);
+
+ // Inject TextureSequence shader details
+ final StringBuilder sFpIns = new StringBuilder();
+ sFpIns.append("uniform ").append(texSeq.getTextureSampler2DType()).append(" mgl_ActiveTexture;\n");
+ sFpIns.append(texSeq.getTextureLookupFragmentShaderImpl());
+ rsFp.insertShaderSource(0, "TEXTURE-SEQUENCE-CODE-BEGIN", 0, sFpIns);
+
+ // Create & Link the shader program
+ final ShaderProgram sp = new ShaderProgram();
+ sp.add(rsVp);
+ sp.add(rsFp);
+ if(!sp.link(gl, System.err)) {
+ throw new GLException("Couldn't link program: "+sp);
+ }
+
+ // Let's manage all our states using ShaderState.
+ st = new ShaderState();
+ st.attachShaderProgram(gl, sp, false);
+ }
+
+ @Override
+ public void init(final GLAutoDrawable drawable) {
+ if(null == texSeq) {
+ throw new InternalError("texSeq null");
+ }
+ final GL2ES2 gl = drawable.getGL().getGL2ES2();
+ final TextureFrame frame = texSeq.getLastTexture();
+ if( null == frame ) {
+ return;
+ }
+ final Texture tex = frame.getTexture();
+
+ initShader(gl);
+
+ // Push the 1st uniform down the path
+ st.useProgram(gl, true);
+
+ final int[] viewPort = new int[] { 0, 0, drawable.getSurfaceWidth(), drawable.getSurfaceHeight()};
+ pmvMatrix = new PMVMatrix();
+ reshapePMV(viewPort[2], viewPort[3]);
+ pmvMatrixUniform = new GLUniformData("mgl_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf());
+ if(!st.uniform(gl, pmvMatrixUniform)) {
+ throw new GLException("Error setting PMVMatrix in shader: "+st);
+ }
+ if(!st.uniform(gl, new GLUniformData("mgl_ActiveTexture", texSeq.getTextureUnit()))) {
+ throw new GLException("Error setting mgl_ActiveTexture in shader: "+st);
+ }
+
+ final float dWidth = drawable.getSurfaceWidth();
+ final float dHeight = drawable.getSurfaceHeight();
+ final float mWidth = tex.getImageWidth();
+ final float mHeight = tex.getImageHeight();
+ final float mAspect = mWidth/mHeight;
+ System.err.println("XXX0: mov aspect: "+mAspect);
+ float xs, ys;
+ if(orthoProjection) {
+ if(mPlayerScaleOrig && mWidth < dWidth && mHeight < dHeight) {
+ xs = mWidth/2f; ys = xs / mAspect;
+ } else {
+ xs = dWidth/2f; ys = xs / mAspect; // w>h
+ }
+ } else {
+ if(mPlayerScaleOrig && mWidth < dWidth && mHeight < dHeight) {
+ xs = mAspect * ( mWidth / dWidth ) ; ys = xs / mAspect ;
+ } else {
+ xs = mAspect; ys = 1f; // b>h
+ }
+ }
+ verts = new float[] { -1f*xs, -1f*ys, 0f, // LB
+ 1f*xs, 1f*ys, 0f // RT
+ };
+ {
+ System.err.println("XXX0: pixel LB: "+verts[0]+", "+verts[1]+", "+verts[2]);
+ System.err.println("XXX0: pixel RT: "+verts[3]+", "+verts[4]+", "+verts[5]);
+ final float[] winLB = new float[3];
+ final float[] winRT = new float[3];
+ pmvMatrix.gluProject(verts[0], verts[1], verts[2], viewPort, 0, winLB, 0);
+ pmvMatrix.gluProject(verts[3], verts[4], verts[5], viewPort, 0, winRT, 0);
+ System.err.println("XXX0: win LB: "+winLB[0]+", "+winLB[1]+", "+winLB[2]);
+ System.err.println("XXX0: win RT: "+winRT[0]+", "+winRT[1]+", "+winRT[2]);
+ }
+
+ interleavedVBO = GLArrayDataServer.createGLSLInterleaved(3+4+2, GL.GL_FLOAT, false, 3*4, GL.GL_STATIC_DRAW);
+ {
+ interleavedVBO.addGLSLSubArray("mgl_Vertex", 3, GL.GL_ARRAY_BUFFER);
+ interleavedVBO.addGLSLSubArray("mgl_Color", 4, GL.GL_ARRAY_BUFFER);
+ interleavedVBO.addGLSLSubArray("mgl_MultiTexCoord", 2, GL.GL_ARRAY_BUFFER);
+ }
+ updateInterleavedVBO(gl, tex);
+
+ st.ownAttribute(interleavedVBO, true);
+ gl.glClearColor(0.3f, 0.3f, 0.3f, 0.3f);
+
+ gl.glEnable(GL.GL_DEPTH_TEST);
+
+ st.useProgram(gl, false);
+
+ // Let's show the completed shader state ..
+ System.out.println("iVBO: "+interleavedVBO);
+ System.out.println(st);
+ }
+
+ protected void updateInterleavedVBO(final GL gl, final Texture tex) {
+ final float ss = 1f, ts = 1f; // scale tex-coord
+ final boolean wasEnabled = interleavedVBO.enabled();
+ interleavedVBO.seal(gl, false);
+ interleavedVBO.rewind();
+ {
+ final FloatBuffer ib = (FloatBuffer)interleavedVBO.getBuffer();
+ final TextureCoords tc = tex.getImageTexCoords();
+ System.err.println("XXX0: "+tc);
+ System.err.println("XXX0: tex aspect: "+tex.getAspectRatio());
+ System.err.println("XXX0: tex y-flip: "+tex.getMustFlipVertically());
+
+ // left-bottom
+ ib.put(verts[0]); ib.put(verts[1]); ib.put(verts[2]);
+ if( hasEffect(EFFECT_GRADIENT_BOTTOM2TOP) ) {
+ ib.put( 0); ib.put( 0); ib.put( 0); ib.put(alpha);
+ } else {
+ ib.put( 1); ib.put( 1); ib.put( 1); ib.put(alpha);
+ }
+ ib.put( tc.left() *ss); ib.put( tc.bottom() *ts);
+
+ // right-bottom
+ ib.put(verts[3]); ib.put(verts[1]); ib.put(verts[2]);
+ if( hasEffect(EFFECT_GRADIENT_BOTTOM2TOP) ) {
+ ib.put( 0); ib.put( 0); ib.put( 0); ib.put(alpha);
+ } else {
+ ib.put( 1); ib.put( 1); ib.put( 1); ib.put(alpha);
+ }
+ ib.put( tc.right() *ss); ib.put( tc.bottom() *ts);
+
+ // left-top
+ ib.put(verts[0]); ib.put(verts[4]); ib.put(verts[2]);
+ ib.put( 1); ib.put( 1); ib.put( 1); ib.put(alpha);
+ ib.put( tc.left() *ss); ib.put( tc.top() *ts);
+
+ // right-top
+ ib.put(verts[3]); ib.put(verts[4]); ib.put(verts[2]);
+ ib.put( 1); ib.put( 1); ib.put( 1); ib.put(alpha);
+ ib.put( tc.right() *ss); ib.put( tc.top() *ts);
+ }
+ interleavedVBO.seal(gl, true);
+ if( !wasEnabled ) {
+ interleavedVBO.enableBuffer(gl, false);
+ }
+ }
+
+ @Override
+ public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) {
+ final GL2ES2 gl = drawable.getGL().getGL2ES2();
+
+ if(null != st) {
+ reshapePMV(width, height);
+ st.useProgram(gl, true);
+ st.uniform(gl, pmvMatrixUniform);
+ st.useProgram(gl, false);
+ }
+
+ System.out.println("pR "+texSeq);
+ }
+
+ private final float zNear = 1f;
+ private final float zFar = 10f;
+
+ private void reshapePMV(final int width, final int height) {
+ pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
+ pmvMatrix.glLoadIdentity();
+ if(orthoProjection) {
+ final float fw = width / 2f;
+ final float fh = height/ 2f;
+ pmvMatrix.glOrthof(-fw, fw, -fh, fh, -1.0f, 1.0f);
+ nearPlaneNormalized = 0f;
+ } else {
+ pmvMatrix.gluPerspective(45.0f, (float)width / (float)height, zNear, zFar);
+ nearPlaneNormalized = 1f/(10f-1f);
+ }
+ System.err.println("XXX0: Perspective nearPlaneNormalized: "+nearPlaneNormalized);
+
+ pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
+ pmvMatrix.glLoadIdentity();
+ pmvMatrix.glTranslatef(0, 0, zoom);
+ }
+
+ @Override
+ public void dispose(final GLAutoDrawable drawable) {
+ if(null == texSeq) { return; }
+ disposeImpl(drawable, true);
+ }
+ private void disposeImpl(final GLAutoDrawable drawable, final boolean disposeTexSeq) {
+ if( disposeTexSeq ) {
+ texSeq = null;
+ }
+ pmvMatrixUniform = null;
+ pmvMatrix=null;
+ if(null != st) {
+ final GL2ES2 gl = drawable.getGL().getGL2ES2();
+ st.destroy(gl);
+ st=null;
+ }
+ }
+
+ @Override
+ public void display(final GLAutoDrawable drawable) {
+ if(null == texSeq) { return; }
+ final 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);
+ pmvMatrix.glLoadIdentity();
+ pmvMatrix.glTranslatef(0, 0, zoom);
+ if(zrot > 0f) {
+ pmvMatrix.glRotatef(zrot, 0, 0, 1);
+ } else {
+ zrot = 0;
+ }
+ st.uniform(gl, pmvMatrixUniform);
+ interleavedVBO.enableBuffer(gl, true);
+ Texture tex = null;
+ if(null!=texSeq) {
+ final TextureSequence.TextureFrame texFrame;
+ if( texSeqShared ) {
+ texFrame = texSeq.getLastTexture();
+ } else {
+ texFrame = texSeq.getNextTexture(gl);
+ }
+ if(null != texFrame) {
+ tex = texFrame.getTexture();
+ gl.glActiveTexture(GL.GL_TEXTURE0+texSeq.getTextureUnit());
+ tex.enable(gl);
+ tex.bind(gl);
+ }
+ }
+ gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, 4);
+ if(null != tex) {
+ tex.disable(gl);
+ }
+ interleavedVBO.enableBuffer(gl, false);
+ st.useProgram(gl, false);
+ }
+}
diff --git a/src/demos/com/jogamp/opengl/demos/graph/TextRendererGLELBase.java b/src/demos/com/jogamp/opengl/demos/graph/TextRendererGLELBase.java
index 61240e4a2..7ab5e6b8c 100644
--- a/src/demos/com/jogamp/opengl/demos/graph/TextRendererGLELBase.java
+++ b/src/demos/com/jogamp/opengl/demos/graph/TextRendererGLELBase.java
@@ -133,6 +133,10 @@ public abstract class TextRendererGLELBase implements GLEventListener {
public void setFlipVerticalInGLOrientation(final boolean v) { flipVerticalInGLOrientation=v; }
public final RegionRenderer getRenderer() { return renderer; }
public final TextRegionUtil getTextRenderUtil() { return textRenderUtil; }
+ public int[] getVBAASampleCount() { return this.vbaaSampleCount; }
+
+ public PMVMatrix getMatrix() { return rs.getMatrix(); };
+ public boolean isMatrixShared() { return !exclusivePMVMatrix; };
@Override
public void init(final GLAutoDrawable drawable) {
@@ -276,9 +280,9 @@ public abstract class TextRendererGLELBase implements GLEventListener {
if( cacheRegion ) {
textRenderUtil.drawString3D(gl, renderer, font, text, null, vbaaSampleCount);
} else if( null != region ) {
- TextRegionUtil.drawString3D(gl, region, renderer, font, text, null, vbaaSampleCount, tempT1, tempT1);
+ TextRegionUtil.drawString3D(gl, region, renderer, font, text, null, vbaaSampleCount, tempT1, tempT2);
} else {
- TextRegionUtil.drawString3D(gl, renderModes, renderer, font, text, null, vbaaSampleCount, tempT1, tempT1);
+ TextRegionUtil.drawString3D(gl, renderModes, renderer, font, text, null, vbaaSampleCount, tempT1, tempT2);
}
renderer.enable(gl, false);
@@ -288,4 +292,47 @@ public abstract class TextRendererGLELBase implements GLEventListener {
lastRow = row + newLineCount;
}
}
+ public void renderRegion(final GLAutoDrawable drawable,
+ final Font font, final float pixelSize,
+ final int column, final int row,
+ final float tx, final float ty, final float tz, final GLRegion region) {
+ if( null != renderer ) {
+ final GL2ES2 gl = drawable.getGL().getGL2ES2();
+
+ float dx = tx;
+ float dy;
+
+ if( !exclusivePMVMatrix ) {
+ dy = 1f-ty;
+ } else {
+ final int height = drawable.getSurfaceHeight();
+ dy = height-ty;
+ }
+ final float sxy = pixelScale * pixelSize;
+ final float lineHeight = font.getLineHeight();
+ dx += sxy * font.getAdvanceWidth('X') * column;
+ dy -= sxy * lineHeight * ( row + 1 );
+
+ final PMVMatrix pmvMatrix = rs.getMatrix();
+ pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
+ if( !exclusivePMVMatrix ) {
+ pmvMatrix.glPushMatrix();
+ } else {
+ pmvMatrix.glLoadIdentity();
+ }
+ pmvMatrix.glTranslatef(dx, dy, tz);
+ if( flipVerticalInGLOrientation && drawable.isGLOriented() ) {
+ pmvMatrix.glScalef(sxy, -1f*sxy, 1.0f);
+ } else {
+ pmvMatrix.glScalef(sxy, sxy, 1.0f);
+ }
+ renderer.enable(gl, true);
+ region.draw(gl, renderer, vbaaSampleCount);
+ renderer.enable(gl, false);
+
+ if( !exclusivePMVMatrix ) {
+ pmvMatrix.glPopMatrix();
+ }
+ }
+ }
}
diff --git a/src/demos/com/jogamp/opengl/demos/graph/ui/GPUUISceneGLListener0A.java b/src/demos/com/jogamp/opengl/demos/graph/ui/GPUUISceneGLListener0A.java
index 990143de8..c73cb7526 100644
--- a/src/demos/com/jogamp/opengl/demos/graph/ui/GPUUISceneGLListener0A.java
+++ b/src/demos/com/jogamp/opengl/demos/graph/ui/GPUUISceneGLListener0A.java
@@ -585,7 +585,7 @@ public class GPUUISceneGLListener0A implements GLEventListener {
mPlayer.setAudioVolume( mPlayerButton.isToggleOn() ? 1f : 0f );
} } );
buttons.add(mPlayerButton);
- mPlayer.initStream(filmURL, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.TEXTURE_COUNT_DEFAULT);
+ mPlayer.playStream(filmURL, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.TEXTURE_COUNT_DEFAULT);
}
if( true ) {
final ImageSequence imgSeq = new ImageSequence(texUnitImageButton, true);
@@ -943,6 +943,7 @@ public class GPUUISceneGLListener0A implements GLEventListener {
@Override
public void mouseWheelMoved(final MouseEvent e) {
final Shape.EventInfo shapeEvent = (Shape.EventInfo) e.getAttachment();
+ /**
final boolean isOnscreen = PointerClass.Onscreen == e.getPointerType(0).getPointerClass();
if( 0 == ( ~InputEvent.BUTTONALL_MASK & e.getModifiers() ) && !isOnscreen ) {
// offscreen vertical mouse wheel zoom
@@ -958,8 +959,14 @@ public class GPUUISceneGLListener0A implements GLEventListener {
VectorUtil.scaleVec3(rot, rot, 2f);
}
shapeEvent.shape.getRotation().rotateByEuler( rot );
- }
+ } */
+ final float[] rot = VectorUtil.scaleVec3(e.getRotation(), e.getRotation(), FloatUtil.PI / 180.0f);
+ // swap axis for onscreen rotation matching natural feel
+ final float tmp = rot[0]; rot[0] = rot[1]; rot[1] = tmp;
+ VectorUtil.scaleVec3(rot, rot, 2f);
+ shapeEvent.shape.getRotation().rotateByEuler( rot );
}
+ /**
@Override
public void gestureDetected(final GestureEvent e) {
final Shape.EventInfo shapeEvent = (Shape.EventInfo) e.getAttachment();
@@ -969,5 +976,6 @@ public class GPUUISceneGLListener0A implements GLEventListener {
System.err.println("Rotate.Zoom.G: "+tz);
shapeEvent.shape.move(0f, 0f, tz);
}
- } };
+ } */
+ };
}
diff --git a/src/demos/com/jogamp/opengl/demos/graph/ui/GPUUISceneTextAnim01.java b/src/demos/com/jogamp/opengl/demos/graph/ui/GPUUISceneTextAnim01.java
index 45bfd53f1..8658fdf4d 100644
--- a/src/demos/com/jogamp/opengl/demos/graph/ui/GPUUISceneTextAnim01.java
+++ b/src/demos/com/jogamp/opengl/demos/graph/ui/GPUUISceneTextAnim01.java
@@ -317,35 +317,5 @@ public class GPUUISceneTextAnim01 implements GLEventListener {
actionText = String.format((Locale)null, "Pos %6.2f / %6.2f / %6.2f", tx[0], tx[1], tx[2]);
}
}
-
- @Override
- public void mouseWheelMoved(final MouseEvent e) {
- final Shape.EventInfo shapeEvent = (Shape.EventInfo) e.getAttachment();
- final boolean isOnscreen = PointerClass.Onscreen == e.getPointerType(0).getPointerClass();
- if( 0 == ( ~InputEvent.BUTTONALL_MASK & e.getModifiers() ) && !isOnscreen ) {
- // offscreen vertical mouse wheel zoom
- final float tz = 100f*e.getRotation()[1]; // vertical: wheel
- System.err.println("Rotate.Zoom.W: "+tz);
- shapeEvent.shape.move(0f, 0f, tz);
- } else if( isOnscreen || e.isControlDown() ) {
- final float[] rot = VectorUtil.scaleVec3(e.getRotation(), e.getRotation(), FloatUtil.PI / 180.0f);
- if( isOnscreen ) {
- System.err.println("XXX: "+e);
- // swap axis for onscreen rotation matching natural feel
- final float tmp = rot[0]; rot[0] = rot[1]; rot[1] = tmp;
- VectorUtil.scaleVec3(rot, rot, 2f);
- }
- shapeEvent.shape.getRotation().rotateByEuler( rot );
- }
- }
- @Override
- public void gestureDetected(final GestureEvent e) {
- final Shape.EventInfo shapeEvent = (Shape.EventInfo) e.getAttachment();
- if( e instanceof PinchToZoomGesture.ZoomEvent ) {
- final PinchToZoomGesture.ZoomEvent ze = (PinchToZoomGesture.ZoomEvent) e;
- final float tz = ze.getDelta() * ze.getScale();
- System.err.println("Rotate.Zoom.G: "+tz);
- shapeEvent.shape.move(0f, 0f, tz);
- }
- } };
+ };
}
diff --git a/src/graphui/classes/com/jogamp/graph/ui/gl/shapes/MediaButton.java b/src/graphui/classes/com/jogamp/graph/ui/gl/shapes/MediaButton.java
index 290abba6e..241fad389 100644
--- a/src/graphui/classes/com/jogamp/graph/ui/gl/shapes/MediaButton.java
+++ b/src/graphui/classes/com/jogamp/graph/ui/gl/shapes/MediaButton.java
@@ -105,7 +105,7 @@ public class MediaButton extends TexSeqButton {
public void run() {
// loop for-ever ..
mPlayer.seek(0);
- mPlayer.play();
+ mPlayer.resume();
} }.start();
} else if( 0 != ( GLMediaEventListener.EVENT_CHANGE_ERR & event_mask ) ) {
final StreamException se = mPlayer.getStreamException();
@@ -128,7 +128,7 @@ public class MediaButton extends TexSeqButton {
try {
mPlayer.initGL(gl);
mPlayer.setAudioVolume( 0f );
- mPlayer.play();
+ mPlayer.resume();
markStateDirty();
} catch (final Exception e) {
e.printStackTrace();
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 c2de32372..5740dae4b 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java
@@ -37,6 +37,7 @@ import com.jogamp.common.net.Uri;
import com.jogamp.opengl.util.texture.Texture;
import com.jogamp.opengl.util.texture.TextureSequence;
import com.jogamp.opengl.util.TimeFrameI;
+import com.jogamp.opengl.util.av.GLMediaPlayer.State;
/**
* GLMediaPlayer interface specifies a {@link TextureSequence} state machine
@@ -45,7 +46,7 @@ import com.jogamp.opengl.util.TimeFrameI;
* Audio maybe supported and played back internally or via an {@link AudioSink} implementation.
* </p>
* <p>
- * Audio and video streams can be selected or muted via {@link #initStream(Uri, int, int, int)}
+ * Audio and video streams can be selected or muted via {@link #playStream(Uri, int, int, int)}
* using the appropriate <a href="#streamIDs">stream id</a>'s.
* </p>
* <p>
@@ -56,7 +57,7 @@ import com.jogamp.opengl.util.TimeFrameI;
* <p>
* Most of the stream processing is performed on the decoding thread, a.k.a. <i>StreamWorker</i>:
* <ul>
- * <li>Stream initialization triggered by {@link #initStream(Uri, int, int, int) initStream(..)} - User gets notified whether the stream has been initialized or not via {@link GLMediaEventListener#attributesChanged(GLMediaPlayer, int, long) attributesChanges(..)}.</li>
+ * <li>Stream initialization triggered by {@link #playStream(Uri, int, int, int) playStream(..)} - User gets notified whether the stream has been initialized or not via {@link GLMediaEventListener#attributesChanged(GLMediaPlayer, int, long) attributesChanges(..)}.</li>
* <li>Stream decoding - User gets notified of a new frame via {@link GLMediaEventListener#newFrameAvailable(GLMediaPlayer, com.jogamp.opengl.util.texture.TextureSequence.TextureFrame, long) newFrameAvailable(...)}.</li>
* <li>Caught <a href="#streamerror">exceptions on the decoding thread</a> are delivered as {@link StreamException}s.</li>
* </ul>
@@ -82,16 +83,17 @@ 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#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 #playStream(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}, {@link State#Uninitialized Uninitialized} </td> <td>{@link State#Playing Playing}, {@link State#Uninitialized Uninitialized}</td> <td>{@link GLMediaEventListener#EVENT_CHANGE_PLAY EVENT_CHANGE_PLAY} or ( {@link GLMediaEventListener#EVENT_CHANGE_ERR EVENT_CHANGE_ERR} + {@link GLMediaEventListener#EVENT_CHANGE_UNINIT EVENT_CHANGE_UNINIT} )</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 #resume()}</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 #stop()}</td> <td>{@link State#Playing Playing}, {@link State#Paused Paused}</td> <td>{@link State#Uninitialized Uninitialized}</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>
+ * <tr><td>{@link #getNextTexture(GL)}</td> <td><i>any</i></td> <td><i>same</i></td> <td>none</td></tr>
+ * <tr><td>{@link #getLastTexture()}</td> <td><i>any</i></td> <td><i>same</i></td> <td>none</td></tr>
* <tr><td>{@link TextureFrame#END_OF_STREAM_PTS END_OF_STREAM}</td> <td>{@link State#Playing Playing}</td> <td>{@link State#Paused Paused}</td> <td>{@link GLMediaEventListener#EVENT_CHANGE_EOS EVENT_CHANGE_EOS} + {@link GLMediaEventListener#EVENT_CHANGE_PAUSE EVENT_CHANGE_PAUSE}</td></tr>
- * <tr><td>{@link StreamException}</td> <td>ANY</td> <td>{@link State#Paused Paused}, {@link State#Uninitialized Uninitialized}</td> <td>{@link GLMediaEventListener#EVENT_CHANGE_ERR EVENT_CHANGE_ERR} + ( {@link GLMediaEventListener#EVENT_CHANGE_PAUSE EVENT_CHANGE_PAUSE} or {@link GLMediaEventListener#EVENT_CHANGE_UNINIT EVENT_CHANGE_UNINIT} )</td></tr>
- * <tr><td>{@link #destroy(GL)}</td> <td>ANY</td> <td>{@link State#Uninitialized Uninitialized}</td> <td>{@link GLMediaEventListener#EVENT_CHANGE_UNINIT EVENT_CHANGE_UNINIT}</td></tr>
+ * <tr><td>{@link StreamException}</td> <td><i>any</i></td> <td>{@link State#Paused Paused}, {@link State#Uninitialized Uninitialized}</td> <td>{@link GLMediaEventListener#EVENT_CHANGE_ERR EVENT_CHANGE_ERR} + ( {@link GLMediaEventListener#EVENT_CHANGE_PAUSE EVENT_CHANGE_PAUSE} or {@link GLMediaEventListener#EVENT_CHANGE_UNINIT EVENT_CHANGE_UNINIT} )</td></tr>
+ * <tr><td>{@link #destroy(GL)}</td> <td><i>any</i></td> <td>{@link State#Uninitialized Uninitialized}</td> <td>{@link GLMediaEventListener#EVENT_CHANGE_UNINIT EVENT_CHANGE_UNINIT}</td></tr>
* </table>
* </p>
*
@@ -188,6 +190,7 @@ import com.jogamp.opengl.util.TimeFrameI;
*/
public interface GLMediaPlayer extends TextureSequence {
public static final boolean DEBUG = Debug.debug("GLMediaPlayer");
+ public static final boolean DEBUG_AVSYNC = Debug.debug("GLMediaPlayer.AVSync");
public static final boolean DEBUG_NATIVE = Debug.debug("GLMediaPlayer.Native");
/** Default texture count, value {@value}. */
@@ -372,7 +375,7 @@ public interface GLMediaPlayer extends TextureSequence {
* @throws IllegalArgumentException if arguments are invalid
* @since 2.3.0
*/
- public void initStream(Uri streamLoc, int vid, int aid, int textureCount) throws IllegalStateException, IllegalArgumentException;
+ public void playStream(Uri streamLoc, int vid, int aid, int textureCount) throws IllegalStateException, IllegalArgumentException;
/**
* Returns the {@link StreamException} caught in the decoder thread, or <code>null</code> if none occured.
@@ -389,7 +392,7 @@ public interface GLMediaPlayer extends TextureSequence {
* <p>
* <a href="#lifecycle">Lifecycle</a>: {@link State#Initialized} -> {@link State#Paused} or {@link State#Initialized}
* </p>
- * Argument <code>gl</code> is ignored if video is muted, see {@link #initStream(Uri, int, int, int)}.
+ * Argument <code>gl</code> is ignored if video is muted, see {@link #playStream(Uri, int, int, int)}.
*
* @param gl current GL object. Maybe <code>null</code>, for audio only.
* @throws IllegalStateException if not invoked in {@link State#Initialized}.
@@ -401,7 +404,7 @@ public interface GLMediaPlayer extends TextureSequence {
/**
* If implementation uses a {@link AudioSink}, it's instance will be returned.
* <p>
- * The {@link AudioSink} instance is available after {@link #initStream(Uri, int, int, int)},
+ * The {@link AudioSink} instance is available after {@link #playStream(Uri, int, int, int)},
* if used by implementation.
* </p>
*/
@@ -416,6 +419,14 @@ public interface GLMediaPlayer extends TextureSequence {
public State destroy(GL gl);
/**
+ * Stops streaming and releases the GL, stream and other resources, but keeps {@link #attachObject(String, Object) attached user objects}.
+ * <p>
+ * <a href="#lifecycle">Lifecycle</a>: <code>ANY</code> -> {@link State#Uninitialized}
+ * </p>
+ */
+ public State stop();
+
+ /**
* Sets the playback speed.
* <p>
* To simplify test, play speed is <i>normalized</i>, i.e.
@@ -452,7 +463,7 @@ public interface GLMediaPlayer extends TextureSequence {
* <a href="#lifecycle">Lifecycle</a>: {@link State#Paused} -> {@link State#Playing}
* </p>
*/
- public State play();
+ public State resume();
/**
* Pauses the <i>StreamWorker</i> decoding thread.
@@ -460,7 +471,7 @@ public interface GLMediaPlayer extends TextureSequence {
* <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,
+ * If a <i>new</i> frame is desired after the next {@link #resume()} call,
* e.g. to make a snapshot of a camera input stream,
* <code>flush</code> shall be set to <code>true</code>.
* </p>
@@ -498,13 +509,13 @@ public interface GLMediaPlayer extends TextureSequence {
public int getAID();
/**
- * @return the current decoded frame count since {@link #play()} and {@link #seek(int)}
+ * @return the current decoded frame count since {@link #resume()} and {@link #seek(int)}
* as increased by {@link #getNextTexture(GL)} or the decoding thread.
*/
public int getDecodedFrameCount();
/**
- * @return the current presented frame count since {@link #play()} and {@link #seek(int)}
+ * @return the current presented frame count since {@link #resume()} and {@link #seek(int)}
* as increased by {@link #getNextTexture(GL)} for new frames.
*/
public int getPresentedFrameCount();
@@ -547,7 +558,7 @@ public interface GLMediaPlayer extends TextureSequence {
public TextureSequence.TextureFrame getNextTexture(GL gl) throws IllegalStateException;
/**
- * Return the stream location, as set by {@link #initStream(Uri, int, int, int)}.
+ * Return the stream location, as set by {@link #playStream(Uri, int, int, int)}.
* @since 2.3.0
*/
public Uri getUri();
diff --git a/src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java b/src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java
index 09d2dfda0..06eca7128 100644
--- a/src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java
+++ b/src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java
@@ -136,7 +136,7 @@ public class AndroidGLMediaPlayerAPI14 extends GLMediaPlayerImpl {
}
@Override
- protected final boolean playImpl() {
+ protected final boolean resumeImpl() {
playStart = Platform.currentTimeMillis();
if(null != mp) {
try {
@@ -212,7 +212,7 @@ public class AndroidGLMediaPlayerAPI14 extends GLMediaPlayerImpl {
protected final int getAudioPTSImpl() { return null != mp ? mp.getCurrentPosition() : 0; }
@Override
- protected final void destroyImpl(final GL gl) {
+ protected final void destroyImpl() {
if(null != mp) {
wakeUp(false);
try {
@@ -239,12 +239,18 @@ public class AndroidGLMediaPlayerAPI14 extends GLMediaPlayerImpl {
}
}
+ @Override
+ protected void stopImpl() {
+ destroyImpl();
+ }
+
public static class SurfaceTextureFrame extends TextureSequence.TextureFrame {
public SurfaceTextureFrame(final Texture t, final SurfaceTexture stex) {
super(t);
this.surfaceTex = stex;
}
+ @Override
public String toString() {
return "SurfaceTextureFrame[pts " + pts + " ms, l " + duration + " ms, texID "+ texture.getTextureObject() + ", " + surfaceTex + "]";
}
diff --git a/src/jogl/classes/jogamp/opengl/openal/av/ALAudioSink.java b/src/jogl/classes/jogamp/opengl/openal/av/ALAudioSink.java
index bdd9b6c95..c52c59f17 100644
--- a/src/jogl/classes/jogamp/opengl/openal/av/ALAudioSink.java
+++ b/src/jogl/classes/jogamp/opengl/openal/av/ALAudioSink.java
@@ -89,6 +89,7 @@ public class ALAudioSink implements AudioSink {
/** Get this frame's OpenAL buffer name */
public final int getALBuffer() { return alBuffer; }
+ @Override
public String toString() {
return "ALAudioFrame[pts " + pts + " ms, l " + duration + " ms, " + byteSize + " bytes, buffer "+alBuffer+"]";
}
diff --git a/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java b/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java
index 01e04f6de..d29464552 100644
--- a/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java
+++ b/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java
@@ -28,6 +28,9 @@
package jogamp.opengl.util.av;
import java.io.IOException;
+import java.net.URISyntaxException;
+import java.net.URLConnection;
+import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@@ -46,9 +49,11 @@ import com.jogamp.opengl.GLProfile;
import jogamp.opengl.Debug;
import com.jogamp.common.net.UriQueryProps;
+import com.jogamp.common.nio.Buffers;
import com.jogamp.common.ExceptionUtils;
import com.jogamp.common.net.Uri;
import com.jogamp.common.os.Platform;
+import com.jogamp.common.util.IOUtil;
import com.jogamp.common.util.InterruptSource;
import com.jogamp.common.util.InterruptedRuntimeException;
import com.jogamp.common.util.LFRingbuffer;
@@ -60,6 +65,8 @@ import com.jogamp.opengl.util.av.AudioSink;
import com.jogamp.opengl.util.av.GLMediaPlayer;
import com.jogamp.opengl.util.glsl.ShaderCode;
import com.jogamp.opengl.util.texture.Texture;
+import com.jogamp.opengl.util.texture.TextureData;
+import com.jogamp.opengl.util.texture.TextureIO;
import com.jogamp.opengl.util.texture.TextureSequence;
import com.jogamp.opengl.util.texture.TextureSequence.TextureFrame;
@@ -96,12 +103,12 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
private final int[] texWrapST = { GL.GL_CLAMP_TO_EDGE, GL.GL_CLAMP_TO_EDGE };
/** User requested URI stream location. */
- private Uri streamLoc = null;
+ private Uri streamLoc;
/**
* In case {@link #streamLoc} is a {@link GLMediaPlayer#CameraInputScheme},
* {@link #cameraPath} holds the URI's path portion
- * as parsed in {@link #initStream(Uri, int, int, int)}.
+ * as parsed in {@link #playStream(Uri, int, int, int)}.
* @see #cameraProps
*/
protected Uri.Encoded cameraPath = null;
@@ -112,9 +119,9 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
private float audioVolume = 1.0f;
/** Shall be set by the {@link #initStreamImpl(int, int)} method implementation. */
- private int vid = GLMediaPlayer.STREAM_ID_AUTO;
+ private int vid = GLMediaPlayer.STREAM_ID_NONE;
/** Shall be set by the {@link #initStreamImpl(int, int)} method implementation. */
- private int aid = GLMediaPlayer.STREAM_ID_AUTO;
+ private int aid = GLMediaPlayer.STREAM_ID_NONE;
/** Shall be set by the {@link #initStreamImpl(int, int)} method implementation. */
private int width = 0;
/** Shall be set by the {@link #initStreamImpl(int, int)} method implementation. */
@@ -202,6 +209,9 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
this.texUnit = 0;
this.textureFragmentShaderHashCode = 0;
this.state = State.Uninitialized;
+ try {
+ streamLoc = Uri.cast("https://no/stream/");
+ } catch (final URISyntaxException e) { }
}
@Override
@@ -237,15 +247,8 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
@Override
public final int[] getTextureWrapST() { return texWrapST; }
- private final void checkGLInit() {
- if(State.Uninitialized == state || State.Initialized == state ) {
- throw new IllegalStateException("GL not initialized: "+this);
- }
- }
-
@Override
- public String getRequiredExtensionsShaderStub() throws IllegalStateException {
- checkGLInit();
+ public String getRequiredExtensionsShaderStub() {
if(GLES2.GL_TEXTURE_EXTERNAL_OES == textureTarget) {
return ShaderCode.createExtensionDirective(GLExtensions.OES_EGL_image_external, ShaderCode.ENABLE);
}
@@ -253,8 +256,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
}
@Override
- public String getTextureSampler2DType() throws IllegalStateException {
- checkGLInit();
+ public String getTextureSampler2DType() {
switch(textureTarget) {
case GL.GL_TEXTURE_2D:
case GL2GL3.GL_TEXTURE_RECTANGLE:
@@ -273,8 +275,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
* if not overridden by specialization.
*/
@Override
- public String getTextureLookupFunctionName(final String desiredFuncName) throws IllegalStateException {
- checkGLInit();
+ public String getTextureLookupFunctionName(final String desiredFuncName) {
return "texture2D";
}
@@ -286,8 +287,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
* if not overridden by specialization.
*/
@Override
- public String getTextureLookupFragmentShaderImpl() throws IllegalStateException {
- checkGLInit();
+ public String getTextureLookupFragmentShaderImpl() {
return "";
}
@@ -335,12 +335,12 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
protected final void setState(final State s) { state=s; }
@Override
- public final State play() {
+ public final State resume() {
synchronized( stateLock ) {
final State preState = state;
switch( state ) {
case Paused:
- if( playImpl() ) {
+ if( resumeImpl() ) {
resetAVPTS();
if( null != audioSink ) {
audioSink.play(); // cont. w/ new data
@@ -356,7 +356,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
return state;
}
}
- protected abstract boolean playImpl();
+ protected abstract boolean resumeImpl();
@Override
public final State pause(final boolean flush) {
@@ -378,7 +378,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
}
attributesUpdated( event_mask );
if( !pauseImpl() ) {
- play();
+ resume();
}
}
if(DEBUG) { System.err.println("Pause: "+preState+" -> "+state+", "+toString()); }
@@ -388,6 +388,24 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
protected abstract boolean pauseImpl();
@Override
+ public final State stop() {
+ synchronized( stateLock ) {
+ final State preState = state;
+ if( null != streamWorker ) {
+ streamWorker.doStop();
+ streamWorker = null;
+ }
+ resetAVPTSAndFlush();
+ stopImpl();
+ changeState(0, State.Uninitialized);
+ // attachedObjects.clear();
+ if(DEBUG) { System.err.println("Stop: "+preState+" -> "+state+", "+toString()); }
+ return state;
+ }
+ }
+ protected abstract void stopImpl();
+
+ @Override
public final State destroy(final GL gl) {
return destroyImpl(gl, 0, true);
}
@@ -397,15 +415,17 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
streamWorker.doStopImpl(wait);
streamWorker = null;
}
- destroyImpl(gl);
+ resetAVPTSAndFlush();
+ destroyImpl();
removeAllTextureFrames(gl);
+ lastFrame = null;
textureCount=0;
changeState(event_mask, State.Uninitialized);
attachedObjects.clear();
return state;
}
}
- protected abstract void destroyImpl(GL gl);
+ protected abstract void destroyImpl();
@Override
public final int seek(int msec) {
@@ -534,13 +554,14 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
}
@Override
- public final void initStream(final Uri streamLoc, final int vid, final int aid, final int reqTextureCount) throws IllegalStateException, IllegalArgumentException {
+ public final void playStream(final Uri streamLoc, final int vid, final int aid, final int reqTextureCount) throws IllegalStateException, IllegalArgumentException {
synchronized( stateLock ) {
if(State.Uninitialized != state) {
throw new IllegalStateException("Instance not in state unintialized: "+this);
}
if(null == streamLoc) {
- throw new IllegalArgumentException("streamLock is null");
+ initTestStream();
+ return;
}
if( STREAM_ID_NONE != vid ) {
textureCount = validateTextureCount(reqTextureCount);
@@ -617,9 +638,9 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
@Override
public final void initGL(final GL gl) throws IllegalStateException, StreamException, GLException {
synchronized( stateLock ) {
- if(State.Initialized != state ) {
- throw new IllegalStateException("Stream not in state initialized: "+this);
- }
+ // if(State.Initialized != state && State.Uninitialized != state) {
+ // throw new IllegalStateException("Stream not in state [un]initialized: "+this);
+ // }
if( null != streamWorker ) {
final StreamException streamInitErr = getStreamException();
if( null != streamInitErr ) {
@@ -629,7 +650,8 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
}
}
try {
- if( STREAM_ID_NONE != vid ) {
+ if( STREAM_ID_NONE != vid && State.Uninitialized != state ) {
+ resetAVPTSAndFlush();
removeAllTextureFrames(gl);
initGLImpl(gl);
if(DEBUG) {
@@ -645,20 +667,40 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
videoFramesDecoded = new LFRingbuffer<TextureFrame>(TextureFrame[].class, textureCount);
lastFrame = videoFramesFree.getBlocking( );
}
- if( null != streamWorker ) {
- streamWorker.initGL(gl);
+ if( null == streamWorker &&
+ ( TEXTURE_COUNT_MIN < textureCount || STREAM_ID_NONE == vid ) ) // Enable StreamWorker for 'audio only' as well (Bug 918).
+ {
+ streamWorker = new StreamWorker();
}
+ streamWorker.initGL(gl);
+ streamWorker.doResume();
+ changeState(0, State.Paused);
+ resume();
} else {
- removeAllTextureFrames(null);
- initGLImpl(null);
- setTextureFormat(-1, -1);
- setTextureType(-1);
- videoFramesOrig = null;
+ resetAVPTSAndFlush();
+ removeAllTextureFrames(gl);
+ // initGLImpl(gl);
+ // Using a dummy test frame
+ width = TestTexture.singleton.getWidth();
+ height = TestTexture.singleton.getHeight();
+ setTextureFormat(GL.GL_RGBA, GL.GL_RGBA);
+ setTextureType(GL.GL_UNSIGNED_BYTE);
+ textureCount = Math.max(TEXTURE_COUNT_MIN, textureCount);
+ videoFramesOrig = createTestTexFrames(gl, textureCount);
+ if( TEXTURE_COUNT_MIN == textureCount ) {
+ videoFramesFree = null;
+ videoFramesDecoded = null;
+ lastFrame = videoFramesOrig[0];
+ } else {
+ videoFramesFree = new LFRingbuffer<TextureFrame>(videoFramesOrig);
+ videoFramesDecoded = new LFRingbuffer<TextureFrame>(TextureFrame[].class, textureCount);
+ lastFrame = videoFramesFree.getBlocking( );
+ }
videoFramesFree = null;
videoFramesDecoded = null;
- lastFrame = null;
+ lastFrame = videoFramesOrig[0];
+ // changeState(0, State.Paused);
}
- changeState(0, State.Paused);
} catch (final Throwable t) {
destroyImpl(gl, GLMediaEventListener.EVENT_CHANGE_ERR, false /* wait */); // -> GLMediaPlayer.State.Uninitialized
throw new GLException("Error initializing GL resources", t);
@@ -703,6 +745,64 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
}
return texFrames;
}
+ protected TextureFrame[] createTestTexFrames(final GL gl, final int count) {
+ final int[] texNames = new int[count];
+ gl.glGenTextures(count, texNames, 0);
+ final int err = gl.glGetError();
+ if( GL.GL_NO_ERROR != err ) {
+ throw new RuntimeException("TextureNames creation failed (num: "+count+"): err "+toHexString(err));
+ }
+ final TextureFrame[] texFrames = new TextureFrame[count];
+ for(int i=0; i<count; i++) {
+ texFrames[i] = createTestTexImage(gl, texNames[i]);
+ }
+ return texFrames;
+ }
+
+ private static class TestTexture {
+ private static final TextureData singleton;
+ static {
+ TextureData data = null;
+ try {
+ final URLConnection urlConn = IOUtil.getResource("jogamp/opengl/assets/test-ntsc01-28x16.png", NullGLMediaPlayer.class.getClassLoader());
+ if(null != urlConn) {
+ data = TextureIO.newTextureData(GLProfile.getGL2ES2(), urlConn.getInputStream(), false, TextureIO.PNG);
+ }
+ } catch (final Exception e) {
+ e.printStackTrace();
+ }
+ if(null == data) {
+ final int w = 28;
+ final int h = 16;
+ final ByteBuffer buffer = Buffers.newDirectByteBuffer(w*h*4);
+ while(buffer.hasRemaining()) {
+ buffer.put((byte) 0xEA); buffer.put((byte) 0xEA); buffer.put((byte) 0xEA); buffer.put((byte) 0xEA);
+ }
+ buffer.rewind();
+ data = new TextureData(GLProfile.getGL2ES2(),
+ GL.GL_RGBA, w, h, 0,
+ GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, false,
+ false, false, buffer, null);
+ }
+ singleton = data;
+ }
+ }
+ private final TextureSequence.TextureFrame createTestTexImage(final GL gl, final int texName) {
+ final Texture texture = createTexImageImpl(gl, texName, TestTexture.singleton.getWidth(), TestTexture.singleton.getHeight());
+ texture.updateImage(gl, TestTexture.singleton);
+ return new TextureSequence.TextureFrame( texture );
+ }
+ private void initTestStream() {
+ textureCount = TEXTURE_COUNT_MIN;
+ final float _fps = 24f;
+ final int _duration = 10*60*1000; // msec
+ final int _totalFrames = (int) ( (_duration/1000)*_fps );
+ updateAttributes(GLMediaPlayer.STREAM_ID_NONE, GLMediaPlayer.STREAM_ID_NONE,
+ TestTexture.singleton.getWidth(), TestTexture.singleton.getHeight(), 0,
+ 0, 0, _fps,
+ _totalFrames, 0, _duration, "png-static", null);
+ }
+
protected abstract TextureFrame createTexImage(GL gl, int texName);
protected final Texture createTexImageImpl(final GL gl, final int texName, final int tWidth, final int tHeight) {
@@ -763,9 +863,6 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
@Override
public final TextureFrame getLastTexture() throws IllegalStateException {
- if( State.Paused != state && State.Playing != state ) {
- throw new IllegalStateException("Instance not paused or playing: "+this);
- }
return lastFrame;
}
@@ -774,7 +871,6 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
videoFramesOrig = null;
videoFramesFree = null;
videoFramesDecoded = null;
- lastFrame = null;
if( null != texFrames ) {
for(int i=0; i<texFrames.length; i++) {
final TextureFrame frame = texFrames[i];
@@ -799,9 +895,6 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
@Override
public final TextureFrame getNextTexture(final GL gl) throws IllegalStateException {
synchronized( stateLock ) {
- if( State.Paused != state && State.Playing != state ) {
- throw new IllegalStateException("Instance not paused or playing: "+this);
- }
if(State.Playing == state) {
boolean dropFrame = false;
try {
@@ -857,7 +950,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
if( null == videoFramesDecoded || !videoFramesDecoded.isEmpty() ) {
nullFrameCount++;
}
- if( DEBUG ) {
+ if( DEBUG_AVSYNC ) {
final int audio_pts = getAudioPTSImpl();
final int audio_scr = (int) ( ( currentTimeMillis - audio_scr_t0 ) * playSpeed );
final int d_apts;
@@ -897,7 +990,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
// final int d_avpts = d_vpts - d_apts;
if( -VIDEO_DPTS_MAX > d_vpts || d_vpts > VIDEO_DPTS_MAX ) {
// if( -VIDEO_DPTS_MAX > d_avpts || d_avpts > VIDEO_DPTS_MAX ) {
- if( DEBUG ) {
+ if( DEBUG_AVSYNC ) {
System.err.println( "AV*: dT "+(currentTimeMillis-lastTimeMillis)+", "+
getPerfStringImpl( video_scr, video_pts, d_vpts, audio_scr, audio_pts, d_apts, 0 ) + ", "+nextFrame+", playCached " + playCached+ ", dropFrame "+dropFrame);
}
@@ -922,7 +1015,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
dropFrame = true;
}
video_pts_last = video_pts;
- if( DEBUG ) {
+ if( DEBUG_AVSYNC ) {
System.err.println( "AV_: dT "+(currentTimeMillis-lastTimeMillis)+", "+
getPerfStringImpl( video_scr, video_pts, d_vpts,
audio_scr, audio_pts, d_apts,
@@ -1002,7 +1095,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(boolean)}, {@link #seek(int)}, {@link #setPlaySpeed(float)}, {@link #getAudioPTS()}.
+ * i.e. {@link #resume()}, {@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}
@@ -1251,7 +1344,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
preNextTextureImpl(sharedGLCtx.getGL());
sharedGLCtxCurrent = true;
}
- if( null == videoFramesFree ) {
+ if( null == videoFramesFree && STREAM_ID_NONE != vid ) {
throw new InternalError("XXX videoFramesFree is null");
}
}
@@ -1393,7 +1486,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
/**
* Called initially by {@link #initStreamImpl(int, int)}, which
- * is called off-thread by {@link #initStream(Uri, int, int, int)}.
+ * is called off-thread by {@link #playStream(Uri, int, int, int)}.
* <p>
* The latter catches an occurring exception and set the state delivers the error events.
* </p>
@@ -1470,11 +1563,10 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
return;
}
if( wasUninitialized ) {
- if( null != streamWorker ) {
- throw new InternalError("XXX: StreamWorker not null - "+this);
- }
- if( TEXTURE_COUNT_MIN < textureCount || STREAM_ID_NONE == vid ) { // Enable StreamWorker for 'audio only' as well (Bug 918).
- streamWorker = new StreamWorker();
+ if( null == streamWorker ) {
+ if( TEXTURE_COUNT_MIN < textureCount || STREAM_ID_NONE == vid ) { // Enable StreamWorker for 'audio only' as well (Bug 918).
+ streamWorker = new StreamWorker();
+ }
}
if( DEBUG ) {
System.err.println("XXX Initialize @ updateAttributes: "+this);
diff --git a/src/jogl/classes/jogamp/opengl/util/av/NullGLMediaPlayer.java b/src/jogl/classes/jogamp/opengl/util/av/NullGLMediaPlayer.java
index 59dba68f2..528b62db6 100644
--- a/src/jogl/classes/jogamp/opengl/util/av/NullGLMediaPlayer.java
+++ b/src/jogl/classes/jogamp/opengl/util/av/NullGLMediaPlayer.java
@@ -66,7 +66,7 @@ public class NullGLMediaPlayer extends GLMediaPlayerImpl {
}
@Override
- protected final boolean playImpl() {
+ protected final boolean resumeImpl() {
pos_start = Platform.currentTimeMillis();
return true;
}
@@ -77,6 +77,10 @@ public class NullGLMediaPlayer extends GLMediaPlayerImpl {
}
@Override
+ protected final void stopImpl() {
+ }
+
+ @Override
protected final int seekImpl(final int msec) {
pos_ms = msec;
validatePos();
@@ -98,7 +102,7 @@ public class NullGLMediaPlayer extends GLMediaPlayerImpl {
}
@Override
- protected final void destroyImpl(final GL gl) {
+ protected final void destroyImpl() {
if(null != texData) {
texData.destroy();
texData = null;
diff --git a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java
index aae1d75d0..91bef005a 100644
--- a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java
+++ b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java
@@ -297,16 +297,19 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl {
if(!available) {
throw new RuntimeException("FFMPEGMediaPlayer not available");
}
+ psm = new GLPixelStorageModes();
+ initSelf();
+ }
+ private void initSelf() {
moviePtr = natives.createInstance0(this, DEBUG_NATIVE);
if(0==moviePtr) {
throw new GLException("Couldn't create FFMPEGInstance");
}
- psm = new GLPixelStorageModes();
audioSink = null;
}
@Override
- protected final void destroyImpl(final GL gl) {
+ protected final void destroyImpl() {
if (moviePtr != 0) {
natives.destroyInstance0(moviePtr);
moviePtr = 0;
@@ -321,6 +324,12 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl {
}
}
+ @Override
+ protected void stopImpl() {
+ destroyImpl();
+ initSelf();
+ }
+
public static final String dev_video_linux = "/dev/video";
@Override
@@ -394,9 +403,6 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl {
if(0==moviePtr) {
throw new GLException("FFMPEG native instance null");
}
- if(null == audioSink) {
- throw new GLException("AudioSink null");
- }
final int audioQueueLimit;
if( null != gl && STREAM_ID_NONE != getVID() ) {
final GLContextImpl ctx = (GLContextImpl)gl.getContext();
@@ -419,8 +425,10 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl {
System.err.println("initGL: p3 avChosen "+avChosenAudioFormat);
}
- if( STREAM_ID_NONE == getAID() ) {
- audioSink.destroy();
+ if( STREAM_ID_NONE == getAID() || null == audioSink ) {
+ if(null != audioSink) {
+ audioSink.destroy();
+ }
audioSink = AudioSinkFactory.createNull();
audioSink.init(AudioSink.DefaultFormat, 0, AudioSink.DefaultInitialQueueSize, AudioSink.DefaultQueueGrowAmount, audioQueueLimit);
} else {
@@ -475,6 +483,7 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl {
}
setTextureFormat(tif, tf);
setTextureType(tt);
+ setIsGLOriented(false);
if(DEBUG) {
System.err.println("initGL: p5: video "+vPixelFmt+", planes "+vPlanes+", bpp "+vBitsPerPixel+"/"+vBytesPerPixelPerPlane+
", tex "+texWidth+"x"+texHeight+", usesTexLookupShader "+usesTexLookupShader);
@@ -694,10 +703,7 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl {
* Otherwise the call is delegated to it's super class.
*/
@Override
- public final String getTextureLookupFunctionName(final String desiredFuncName) throws IllegalStateException {
- if( State.Uninitialized == getState() ) {
- throw new IllegalStateException("Instance not initialized: "+this);
- }
+ public final String getTextureLookupFunctionName(final String desiredFuncName) {
if( usesTexLookupShader ) {
if(null != desiredFuncName && desiredFuncName.length()>0) {
texLookupFuncName = desiredFuncName;
@@ -714,10 +720,7 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl {
* e.g. YUV420P to RGB. Otherwise the call is delegated to it's super class.
*/
@Override
- public final String getTextureLookupFragmentShaderImpl() throws IllegalStateException {
- if( State.Uninitialized == getState() ) {
- throw new IllegalStateException("Instance not initialized: "+this);
- }
+ public final String getTextureLookupFragmentShaderImpl() {
if( !usesTexLookupShader ) {
return super.getTextureLookupFragmentShaderImpl();
}
@@ -825,7 +828,7 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl {
}
@Override
- public final boolean playImpl() {
+ public final boolean resumeImpl() {
if(0==moviePtr) {
return false;
}
diff --git a/src/jogl/classes/jogamp/opengl/util/av/impl/OMXGLMediaPlayer.java b/src/jogl/classes/jogamp/opengl/util/av/impl/OMXGLMediaPlayer.java
index c69108b04..336084734 100644
--- a/src/jogl/classes/jogamp/opengl/util/av/impl/OMXGLMediaPlayer.java
+++ b/src/jogl/classes/jogamp/opengl/util/av/impl/OMXGLMediaPlayer.java
@@ -86,7 +86,7 @@ public class OMXGLMediaPlayer extends EGLMediaPlayerImpl {
}
@Override
- protected void destroyImpl(final GL gl) {
+ protected void destroyImpl() {
if (moviePtr != 0) {
_stop(moviePtr);
_detachVideoRenderer(moviePtr);
@@ -137,7 +137,7 @@ public class OMXGLMediaPlayer extends EGLMediaPlayerImpl {
}
@Override
- public synchronized boolean playImpl() {
+ public synchronized boolean resumeImpl() {
if(0==moviePtr) {
return false;
}
@@ -155,6 +155,12 @@ public class OMXGLMediaPlayer extends EGLMediaPlayerImpl {
return true;
}
+ @Override
+ protected final void stopImpl() {
+ destroyImpl();
+ initOMX();
+ }
+
/** @return time position after issuing the command */
@Override
protected int seekImpl(final int msec) {
diff --git a/src/jogl/native/libav/ffmpeg_impl_template.c b/src/jogl/native/libav/ffmpeg_impl_template.c
index 76addd9ad..ee91abe5e 100644
--- a/src/jogl/native/libav/ffmpeg_impl_template.c
+++ b/src/jogl/native/libav/ffmpeg_impl_template.c
@@ -363,6 +363,7 @@ static void freeInstance(JNIEnv *env, FFMPEGToolBasicAV_t* pAV) {
int i;
if(NULL != pAV) {
MY_MUTEX_LOCK(env, mutex_avcodec_openclose);
+ pAV->ready = 0;
{
// Close the V codec
if(NULL != pAV->pVCodecCtx) {
@@ -509,6 +510,7 @@ JNIEXPORT jlong JNICALL FF_FUNC(createInstance0)
JoglCommon_throwNewRuntimeException(env, "Couldn't alloc instance");
return 0;
}
+ pAV->ready = 0;
pAV->avcodecVersion = sp_avcodec_version();
pAV->avformatVersion = sp_avformat_version();
pAV->avutilVersion = sp_avutil_version();
@@ -1173,6 +1175,7 @@ JNIEXPORT void JNICALL FF_FUNC(setStream0)
initPTSStats(&pAV->vPTSStats);
initPTSStats(&pAV->aPTSStats);
_updateJavaAttributes(env, pAV);
+ pAV->ready = 1;
}
JNIEXPORT void JNICALL FF_FUNC(setGLFuncs0)
@@ -1197,6 +1200,9 @@ JNIEXPORT jint JNICALL FF_FUNC(readNextPacket0)
(JNIEnv *env, jobject instance, jlong ptr, jint texTarget, jint texFmt, jint texType)
{
FFMPEGToolBasicAV_t *pAV = (FFMPEGToolBasicAV_t *)((void *)((intptr_t)ptr));
+ if( 0 == pAV->ready ) {
+ return 0;
+ }
jint resPTS = INVALID_PTS;
uint8_t * pkt_odata;
@@ -1556,12 +1562,18 @@ JNIEXPORT jint JNICALL FF_FUNC(play0)
(JNIEnv *env, jobject instance, jlong ptr)
{
FFMPEGToolBasicAV_t *pAV = (FFMPEGToolBasicAV_t *)((void *)((intptr_t)ptr));
+ if( 0 == pAV->ready ) {
+ return 0;
+ }
return sp_av_read_play(pAV->pFormatCtx);
}
JNIEXPORT jint JNICALL FF_FUNC(pause0)
(JNIEnv *env, jobject instance, jlong ptr)
{
FFMPEGToolBasicAV_t *pAV = (FFMPEGToolBasicAV_t *)((void *)((intptr_t)ptr));
+ if( 0 == pAV->ready ) {
+ return 0;
+ }
return sp_av_read_pause(pAV->pFormatCtx);
}
@@ -1569,6 +1581,9 @@ JNIEXPORT jint JNICALL FF_FUNC(seek0)
(JNIEnv *env, jobject instance, jlong ptr, jint pos1)
{
const FFMPEGToolBasicAV_t *pAV = (FFMPEGToolBasicAV_t *)((void *)((intptr_t)ptr));
+ if( 0 == pAV->ready ) {
+ return 0;
+ }
int64_t pos0, pts0;
int streamID;
AVRational time_base;
@@ -1627,6 +1642,9 @@ JNIEXPORT jint JNICALL FF_FUNC(getVideoPTS0)
(JNIEnv *env, jobject instance, jlong ptr)
{
FFMPEGToolBasicAV_t *pAV = (FFMPEGToolBasicAV_t *)((void *)((intptr_t)ptr));
+ if( 0 == pAV->ready ) {
+ return 0;
+ }
return pAV->vPTS;
}
@@ -1634,6 +1652,9 @@ JNIEXPORT jint JNICALL FF_FUNC(getAudioPTS0)
(JNIEnv *env, jobject instance, jlong ptr)
{
FFMPEGToolBasicAV_t *pAV = (FFMPEGToolBasicAV_t *)((void *)((intptr_t)ptr));
+ if( 0 == pAV->ready ) {
+ return 0;
+ }
return pAV->aPTS;
}
diff --git a/src/jogl/native/libav/ffmpeg_tool.h b/src/jogl/native/libav/ffmpeg_tool.h
index dd39146e6..02a297f73 100644
--- a/src/jogl/native/libav/ffmpeg_tool.h
+++ b/src/jogl/native/libav/ffmpeg_tool.h
@@ -202,6 +202,8 @@ typedef struct {
char acodec[64];
char vcodec[64];
+ int32_t ready;
+
} FFMPEGToolBasicAV_t ;
#endif /* _FFMPEG_TOOL_H */