aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2013-08-29 22:46:57 +0200
committerSven Gothel <[email protected]>2013-08-29 22:46:57 +0200
commiteca6a5cb1e2beda84dfbafc31ed225e272f4f3fb (patch)
treec77750eac39a611bbc46b77f64e5ae5c123e9427 /src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java
parent9bf14f3c6bf98bd86913bec6e7feb54537f9b7d3 (diff)
Enhance GLMediaPlayer: Full FFMPeg support, 'dshow' camera support on windows, 2 more pixel formats, fail-safe data handling
- add support for ffmpeg 2 / libav 10 -> lavc55_lavf55_lavu52_lavr01 - add support for ffmpeg libswresample (similar to libavresample) - handle BGRA (GL type) and BGR24 (texture shader) - Change Camera URI semantics, drop 'host' and use 'path' for camera ID and use 'query' for options. - add support for Window's DShow camera selection - our camera id -> index of list of video-input devices, this gives us same behavior as w/ Linux - requires windows libs: strmiids, uuid, ole32, oleaut32 - Compiles w/ MingW64, works w/ libav/ffmpeg - TODO: test compilation w/ MingW 32bit ! - don't push data to texture if (linesize <= 0) this may happen due to buggy decoder / setup .. Tested manually on GNU/Linux x64 and Windows x64: - GNU/Linux libav 0.8, libav 9, libav 10, ffmpeg 1.2, ffmpeg 2.0 - Windows libav 0.8, libav 9, ffmpeg 2.0 - videos and camera
Diffstat (limited to 'src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java')
-rw-r--r--src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java45
1 files changed, 36 insertions, 9 deletions
diff --git a/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java b/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java
index 5286c86b8..ab0e2eebd 100644
--- a/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java
+++ b/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java
@@ -31,6 +31,7 @@ import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Iterator;
+import java.util.Map;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.opengl.GL;
@@ -44,6 +45,7 @@ import javax.media.opengl.GLProfile;
import jogamp.opengl.Debug;
+import com.jogamp.common.net.URIQueryProps;
import com.jogamp.common.os.Platform;
import com.jogamp.common.util.LFRingbuffer;
import com.jogamp.common.util.Ringbuffer;
@@ -89,10 +91,13 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
protected URI streamLoc = null;
/**
* In case {@link #streamLoc} is a {@link GLMediaPlayer#CameraInputScheme},
- * {@link #cameraHostPart} holds the URI's path portion
+ * {@link #cameraPath} holds the URI's path portion
* as parsed in {@link #initStream(URI, int, int, int)}.
+ * @see #cameraProps
*/
- protected String cameraHostPart = null;
+ protected String cameraPath = null;
+ /** Optional camera properties, see {@link #cameraPath}. */
+ protected Map<String, String> cameraProps = null;
protected volatile float playSpeed = 1.0f;
protected float audioVolume = 1.0f;
@@ -472,11 +477,19 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
this.streamLoc = streamLoc;
// Pre-parse for camera-input scheme
+ cameraPath = null;
+ cameraProps = null;
final String streamLocScheme = streamLoc.getScheme();
if( null != streamLocScheme && streamLocScheme.equals(CameraInputScheme) ) {
- cameraHostPart = streamLoc.getHost();
- } else {
- cameraHostPart = null;
+ final String rawPath = streamLoc.getRawPath();
+ if( null != rawPath && rawPath.length() > 0 ) {
+ // cut-off root fwd-slash
+ cameraPath = rawPath.substring(1);
+ final URIQueryProps props = URIQueryProps.create(streamLoc);
+ cameraProps = props.getProperties();
+ } else {
+ throw new IllegalArgumentException("Camera path is empty: "+streamLoc.toString());
+ }
}
this.vid = vid;
@@ -526,6 +539,9 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
if( STREAM_ID_NONE != vid ) {
removeAllTextureFrames(gl);
initGLImpl(gl);
+ if(DEBUG) {
+ System.err.println("initGLImpl.X "+this);
+ }
videoFramesOrig = createTexFrames(gl, textureCount);
videoFramesFree = new LFRingbuffer<TextureFrame>(videoFramesOrig);
videoFramesDecoded = new LFRingbuffer<TextureFrame>(TextureFrame[].class, textureCount);
@@ -615,13 +631,13 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
final int err = gl.glGetError();
if( GL.GL_NO_ERROR != err ) {
throw new RuntimeException("Couldn't create TexImage2D RGBA "+tWidth+"x"+tHeight+", target "+toHexString(textureTarget)+
- ", ifmt "+toHexString(GL.GL_RGBA)+", fmt "+toHexString(textureFormat)+", type "+toHexString(textureType)+
+ ", ifmt "+toHexString(textureInternalFormat)+", fmt "+toHexString(textureFormat)+", type "+toHexString(textureType)+
", err "+toHexString(err));
}
}
if(DEBUG) {
System.err.println("Created TexImage2D RGBA "+tWidth+"x"+tHeight+", target "+toHexString(textureTarget)+
- ", ifmt "+toHexString(GL.GL_RGBA)+", fmt "+toHexString(textureFormat)+", type "+toHexString(textureType));
+ ", ifmt "+toHexString(textureInternalFormat)+", fmt "+toHexString(textureFormat)+", type "+toHexString(textureType));
}
}
gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_MIN_FILTER, texMinMagFilter[0]);
@@ -1322,10 +1338,10 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
final int freeVideoFrames = null != videoFramesFree ? videoFramesFree.size() : 0;
final int decVideoFrames = null != videoFramesDecoded ? videoFramesDecoded.size() : 0;
final int video_scr = video_scr_pts + (int) ( ( Platform.currentTimeMillis() - video_scr_t0 ) * playSpeed );
- final String camPath = null != cameraHostPart ? ", camera: "+cameraHostPart : "";
+ final String camPath = null != cameraPath ? ", camera: "+cameraPath : "";
return "GLMediaPlayer["+state+", vSCR "+video_scr+", frames[p "+presentedFrameCount+", d "+decodedFrameCount+", t "+videoFrames+" ("+tt+" s)], "+
"speed "+playSpeed+", "+bps_stream+" bps, "+
- "Texture[count "+textureCount+", free "+freeVideoFrames+", dec "+decVideoFrames+", target "+toHexString(textureTarget)+", format "+toHexString(textureFormat)+", type "+toHexString(textureType)+"], "+
+ "Texture[count "+textureCount+", free "+freeVideoFrames+", dec "+decVideoFrames+", tagt "+toHexString(textureTarget)+", ifmt "+toHexString(textureInternalFormat)+", fmt "+toHexString(textureFormat)+", type "+toHexString(textureType)+"], "+
"Video[id "+vid+", <"+vcodec+">, "+width+"x"+height+", "+fps+" fps, "+frame_duration+" fdur, "+bps_video+" bps], "+
"Audio[id "+aid+", <"+acodec+">, "+bps_audio+" bps, "+audioFrames+" frames], uri "+loc+camPath+"]";
}
@@ -1394,4 +1410,15 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
protected static final String toHexString(int v) {
return "0x"+Integer.toHexString(v);
}
+ protected static final int getPropIntVal(Map<String, String> props, String key) {
+ final String val = props.get(key);
+ try {
+ return Integer.valueOf(val).intValue();
+ } catch (NumberFormatException nfe) {
+ if(DEBUG) {
+ System.err.println("Not a valid integer for <"+key+">: <"+val+">");
+ }
+ }
+ return 0;
+ }
} \ No newline at end of file