aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes
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
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')
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java24
-rw-r--r--src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java4
-rw-r--r--src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java45
-rw-r--r--src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java231
-rw-r--r--src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java105
-rw-r--r--src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGNatives.java19
-rw-r--r--src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGStaticNatives.java5
-rw-r--r--src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGv08Natives.java5
-rw-r--r--src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGv09Natives.java5
-rw-r--r--src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGv10Natives.java81
10 files changed, 366 insertions, 158 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java b/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java
index 0feca9f45..7f57138a7 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java
@@ -197,13 +197,33 @@ public interface GLMediaPlayer extends TextureSequence {
* {@link URI#getScheme() URI scheme} name {@value} for camera input. E.g. <code>camera://0</code>
* for the 1st camera device.
* <p>
- * Note: the {@link URI#getHost() URI host} is being used to identify the camera:
+ * The {@link URI#getRawPath() URI path} is being used to identify the camera,
+ * where the root fwd-slash is being cut-off.
+ * </p>
+ * <p>
+ * The {@link URI#getRawQuery() URI query} is used to pass options to the camera.
+ * </p>
+ * <pre>
+ * camera:/<id>
+ * camera://somewhere/<id>
+ * camera://somewhere/<id>?width=640&height=480&rate=15
+ * </pre>
* <pre>
- * camera://<id>
+ * URI: [scheme:][//authority][path][?query][#fragment]
+ * w/ authority: [user-info@]host[:port]
+ * Note: 'path' starts w/ fwd slash
* </pre>
* </p>
*/
public static final String CameraInputScheme = "camera";
+ /** Camera property {@value}, size as string, e.g. <code>1280x720</code>, <code>hd720</code>. May not be supported on all platforms. See {@link #CameraInputScheme}. */
+ public static final String CameraPropSizeS = "size";
+ /** Camera property {@value}. See {@link #CameraInputScheme}. */
+ public static final String CameraPropWidth = "width";
+ /** Camera property {@value}. See {@link #CameraInputScheme}. */
+ public static final String CameraPropHeight = "height";
+ /** Camera property {@value}. See {@link #CameraInputScheme}. */
+ public static final String CameraPropRate = "rate";
/** Maximum video frame async of {@value} milliseconds. */
public static final int MAXIMUM_VIDEO_ASYNC = 22;
diff --git a/src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java b/src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java
index 056998c0c..38faf62a6 100644
--- a/src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java
+++ b/src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java
@@ -254,12 +254,12 @@ public class AndroidGLMediaPlayerAPI14 extends GLMediaPlayerImpl {
return;
}
if( null == mp && null == cam ) {
- if( null == cameraHostPart ) {
+ if( null == cameraPath ) {
mp = new MediaPlayer();
} else {
int cameraId = 0;
try {
- cameraId = Integer.valueOf(cameraHostPart);
+ cameraId = Integer.valueOf(cameraPath);
} catch (NumberFormatException nfe) {}
if( 0 <= cameraId && cameraId < Camera.getNumberOfCameras() ) {
cam = Camera.open(cameraId);
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
diff --git a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java
index f327cddd4..400788a24 100644
--- a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java
@@ -32,10 +32,8 @@ import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import javax.media.opengl.GLProfile;
@@ -53,12 +51,13 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
private static final List<String> glueLibNames = new ArrayList<String>(); // none
- private static final int symbolCount = 54;
+ private static final int symbolCount = 65;
private static final String[] symbolNames = {
- "avcodec_version",
- "avformat_version",
"avutil_version",
-/* 4 */ "avresample_version",
+ "avformat_version",
+ "avcodec_version",
+ "avresample_version",
+/* 5 */ "swresample_version",
// libavcodec
"avcodec_register_all",
@@ -69,15 +68,20 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
"avcodec_alloc_frame",
"avcodec_get_frame_defaults",
"avcodec_free_frame", // 54.28.0 (opt)
- "avcodec_default_get_buffer",
- "avcodec_default_release_buffer",
+ "avcodec_default_get_buffer", // <= 54 (opt), else sp_avcodec_default_get_buffer2
+ "avcodec_default_release_buffer", // <= 54 (opt), else sp_av_frame_unref
+ "avcodec_default_get_buffer2", // 55 (opt)
+ "avcodec_get_edge_width",
+ "av_image_fill_linesizes",
+ "avcodec_align_dimensions",
+ "avcodec_align_dimensions2",
"avcodec_flush_buffers",
"av_init_packet",
"av_new_packet",
"av_destruct_packet",
"av_free_packet",
"avcodec_decode_audio4", // 53.25.0 (opt)
-/* 21 */ "avcodec_decode_video2", // 52.23.0
+/* 27 */ "avcodec_decode_video2", // 52.23.0
// libavutil
"av_pix_fmt_descriptors",
@@ -91,7 +95,7 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
"av_dict_get",
"av_dict_count", // 54.* (opt)
"av_dict_set",
-/* 33 */ "av_dict_free",
+/* 28 */ "av_dict_free",
// libavformat
"avformat_alloc_context",
@@ -108,22 +112,25 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
"av_read_pause",
"avformat_network_init", // 53.13.0 (opt)
"avformat_network_deinit", // 53.13.0 (opt)
-/* 48 */ "avformat_find_stream_info", // 53.3.0 (opt)
+/* 54 */ "avformat_find_stream_info", // 53.3.0 (opt)
// libavdevice
-/* 49 */ "avdevice_register_all", // ???
+/* 55 */ "avdevice_register_all", // ???
// libavresample
"avresample_alloc_context", // 1.0.1
"avresample_open",
"avresample_close",
"avresample_free",
-/* 54 */ "avresample_convert"
- };
-
- // alternate symbol names
- private static final String[][] altSymbolNames = {
- // { "av_find_stream_info", "avformat_find_stream_info" }, // old, 53.3.0
+/* 60 */ "avresample_convert",
+
+ // libavresample
+ "av_opt_set_sample_fmt", // actually lavu .. but exist only w/ swresample!
+ "swr_alloc",
+ "swr_init",
+ "swr_free",
+/* 65 */ "swr_convert",
+
};
// optional symbol names
@@ -132,8 +139,13 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
"avcodec_free_frame", // 54.28.0 (opt)
"av_frame_unref", // 55.0.0 (opt)
"av_dict_count", // 54.* (opt)
+ "avcodec_default_get_buffer", // <= 54 (opt), else sp_avcodec_default_get_buffer2
+ "avcodec_default_release_buffer", // <= 54 (opt), else sp_av_frame_unref
+ "avcodec_default_get_buffer2", // 55 (opt)
+
// libavdevice
"avdevice_register_all", // 53.0.0 (opt)
+
// libavresample
"avresample_version", // 1.0.1
"avresample_alloc_context", // 1.0.1
@@ -141,41 +153,60 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
"avresample_close",
"avresample_free",
"avresample_convert",
+
+ // libavresample
+ "av_opt_set_sample_fmt", // actually lavu .. but exist only w/ swresample!
+ "swresample_version", // 0
+ "swr_alloc",
+ "swr_init",
+ "swr_free",
+ "swr_convert",
};
private static final long[] symbolAddr = new long[symbolCount];
private static final boolean ready;
- private static final boolean libsLoaded;
+ private static final boolean libsUFCLoaded;
private static final boolean avresampleLoaded; // optional
+ private static final boolean swresampleLoaded; // optional
private static final boolean avdeviceLoaded; // optional
static final VersionNumber avCodecVersion;
static final VersionNumber avFormatVersion;
static final VersionNumber avUtilVersion;
static final VersionNumber avResampleVersion;
+ static final VersionNumber swResampleVersion;
private static final FFMPEGNatives natives;
+ private static final int LIB_IDX_UTI = 0;
+ private static final int LIB_IDX_FMT = 1;
+ private static final int LIB_IDX_COD = 2;
+ private static final int LIB_IDX_DEV = 3;
+ private static final int LIB_IDX_AVR = 4;
+ private static final int LIB_IDX_SWR = 5;
+
static {
// native ffmpeg media player implementation is included in jogl_desktop and jogl_mobile
GLProfile.initSingleton();
boolean _ready = false;
- boolean[] _libsLoaded= { false };
- boolean[] _avdeviceLoaded= { false };
- boolean[] _avresampleLoaded= { false };
- VersionNumber[] _versions = new VersionNumber[4];
+ /** util, format, codec, device, avresample, swresample */
+ boolean[] _loaded= new boolean[6];
+ /** util, format, codec, avresample, swresample */
+ VersionNumber[] _versions = new VersionNumber[5];
try {
- _ready = initSymbols(_libsLoaded, _avdeviceLoaded, _avresampleLoaded, _versions);
+ _ready = initSymbols(_loaded, _versions);
} catch (Throwable t) {
t.printStackTrace();
}
- libsLoaded = _libsLoaded[0];
- avdeviceLoaded = _avdeviceLoaded[0];
- avresampleLoaded = _avresampleLoaded[0];
- avCodecVersion = _versions[0];
+ libsUFCLoaded = _loaded[LIB_IDX_UTI] && _loaded[LIB_IDX_FMT] && _loaded[LIB_IDX_COD];
+ avdeviceLoaded = _loaded[LIB_IDX_DEV];
+ avresampleLoaded = _loaded[LIB_IDX_AVR];
+ swresampleLoaded = _loaded[LIB_IDX_SWR];
+ avUtilVersion = _versions[0];
avFormatVersion = _versions[1];
- avUtilVersion = _versions[2];
+ avCodecVersion = _versions[2];
avResampleVersion = _versions[3];
- if(!libsLoaded) {
- System.err.println("LIB_AV Not Available");
+ swResampleVersion = _versions[4];
+ if(!libsUFCLoaded) {
+ System.err.println("LIB_AV Not Available: lavu, lavc, lavu");
natives = null;
ready = false;
} else if(!_ready) {
@@ -183,12 +214,15 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
natives = null;
ready = false;
} else {
- if( avCodecVersion.getMajor() <= 53 && avFormatVersion.getMajor() <= 53 && avUtilVersion.getMajor() <= 51 ) {
+ if( avCodecVersion.getMajor() == 53 && avFormatVersion.getMajor() == 53 && avUtilVersion.getMajor() == 51 ) {
// lavc53.lavf53.lavu51
natives = new FFMPEGv08Natives();
- } else if( avCodecVersion.getMajor() == 54 && avFormatVersion.getMajor() <= 54 && avUtilVersion.getMajor() <= 52 ) {
+ } else if( avCodecVersion.getMajor() == 54 && avFormatVersion.getMajor() == 54 && avUtilVersion.getMajor() == 52 ) {
// lavc54.lavf54.lavu52.lavr01
natives = new FFMPEGv09Natives();
+ } else if( avCodecVersion.getMajor() == 55 && avFormatVersion.getMajor() == 55 && avUtilVersion.getMajor() == 52 ) {
+ // lavc55.lavf55.lavu52.lavr01
+ natives = new FFMPEGv10Natives();
} else {
System.err.println("LIB_AV No Version/Native-Impl Match");
natives = null;
@@ -201,29 +235,33 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
}
}
- static boolean libsLoaded() { return libsLoaded; }
+ static boolean libsLoaded() { return libsUFCLoaded; }
static boolean avDeviceLoaded() { return avdeviceLoaded; }
static boolean avResampleLoaded() { return avresampleLoaded; }
+ static boolean swResampleLoaded() { return swresampleLoaded; }
static FFMPEGNatives getNatives() { return natives; }
static boolean initSingleton() { return ready; }
-
- private static final boolean initSymbols(boolean[] libsLoaded, boolean[] avdeviceLoaded, boolean[] avresampleLoaded,
- VersionNumber[] versions) {
- libsLoaded[0] = false;
+
+ /**
+ * @param loaded 6: util, format, codec, device, avresample, swresample
+ * @param versions 5: util, format, codec, avresample, swresample
+ * @return
+ */
+ private static final boolean initSymbols(boolean[] loaded, VersionNumber[] versions) {
+ for(int i=0; i<6; i++) {
+ loaded[i] = false;
+ }
final DynamicLibraryBundle dl = AccessController.doPrivileged(new PrivilegedAction<DynamicLibraryBundle>() {
public DynamicLibraryBundle run() {
return new DynamicLibraryBundle(new FFMPEGDynamicLibraryBundleInfo());
} } );
- final boolean avutilLoaded = dl.isToolLibLoaded(0);
- final boolean avformatLoaded = dl.isToolLibLoaded(1);
- final boolean avcodecLoaded = dl.isToolLibLoaded(2);
- if(!avutilLoaded || !avformatLoaded || !avcodecLoaded) {
- throw new RuntimeException("FFMPEG Tool library incomplete: [ avutil "+avutilLoaded+", avformat "+avformatLoaded+", avcodec "+avcodecLoaded+"]");
+ dl.toString();
+ for(int i=0; i<6; i++) {
+ loaded[i] = dl.isToolLibLoaded(i);
+ }
+ if( !loaded[LIB_IDX_UTI] || !loaded[LIB_IDX_FMT] || !loaded[LIB_IDX_COD] ) {
+ throw new RuntimeException("FFMPEG Tool library incomplete: [ avutil "+loaded[LIB_IDX_UTI]+", avformat "+loaded[LIB_IDX_FMT]+", avcodec "+loaded[LIB_IDX_COD]+"]");
}
- avdeviceLoaded[0] = dl.isToolLibLoaded(3);
- avresampleLoaded[0] = dl.isToolLibLoaded(4);
- libsLoaded[0] = true;
-
if(symbolNames.length != symbolCount) {
throw new InternalError("XXX0 "+symbolNames.length+" != "+symbolCount);
}
@@ -232,20 +270,6 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
final Set<String> optionalSymbolNameSet = new HashSet<String>();
optionalSymbolNameSet.addAll(Arrays.asList(optionalSymbolNames));
- // alternate symbol name mapping to indexed array
- final Map<String, Integer> mAltSymbolNames = new HashMap<String, Integer>();
- final int[][] iAltSymbolNames = new int[altSymbolNames.length][];
- {
- final List<String> symbolNameList = Arrays.asList(symbolNames);
- for(int i=0; i<altSymbolNames.length; i++) {
- iAltSymbolNames[i] = new int[altSymbolNames[i].length];
- for(int j=0; j<altSymbolNames[i].length; j++) {
- mAltSymbolNames.put(altSymbolNames[i][j], new Integer(i));
- iAltSymbolNames[i][j] = symbolNameList.indexOf(altSymbolNames[i][j]);
- }
- }
- }
-
// lookup
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
@@ -262,33 +286,18 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
// no symbol, check optional and alternative symbols
final String symbol = symbolNames[i];
if ( !optionalSymbolNameSet.contains(symbol) ) {
- // check for API changed symbols
- boolean ok = false;
- final Integer cI = mAltSymbolNames.get(symbol);
- if ( null != cI ) {
- // check whether alternative symbol is available
- final int ci = cI.intValue();
- for(int j=0; !ok && j<iAltSymbolNames[ci].length; j++) {
- final int si = iAltSymbolNames[ci][j];
- ok = 0 != symbolAddr[si];
- if(ok && DEBUG) {
- System.err.println("OK: Unresolved symbol <"+symbol+">, but has alternative <"+symbolNames[si]+">");
- }
- }
- }
- if(!ok) {
- System.err.println("Fail: Could not resolve symbol <"+symbolNames[i]+">: not optional, no alternatives.");
- res = false;
- }
+ System.err.println("Fail: Could not resolve symbol <"+symbolNames[i]+">: not optional, no alternatives.");
+ res = false;
} else if(DEBUG) {
System.err.println("OK: Unresolved optional symbol <"+symbolNames[i]+">");
}
}
}
- versions[0] = FFMPEGStaticNatives.getAVVersion(FFMPEGStaticNatives.getAvCodecVersion0(symbolAddr[0]));
- versions[1] = FFMPEGStaticNatives.getAVVersion(FFMPEGStaticNatives.getAvFormatVersion0(symbolAddr[1]));
- versions[2] = FFMPEGStaticNatives.getAVVersion(FFMPEGStaticNatives.getAvUtilVersion0(symbolAddr[2]));
- versions[3] = FFMPEGStaticNatives.getAVVersion(FFMPEGStaticNatives.getAvResampleVersion0(symbolAddr[3]));
+ versions[0] = FFMPEGStaticNatives.getAVVersion(FFMPEGStaticNatives.getAvVersion0(symbolAddr[0]));
+ versions[1] = FFMPEGStaticNatives.getAVVersion(FFMPEGStaticNatives.getAvVersion0(symbolAddr[1]));
+ versions[2] = FFMPEGStaticNatives.getAVVersion(FFMPEGStaticNatives.getAvVersion0(symbolAddr[2]));
+ versions[3] = FFMPEGStaticNatives.getAVVersion(FFMPEGStaticNatives.getAvVersion0(symbolAddr[3]));
+ versions[4] = FFMPEGStaticNatives.getAVVersion(FFMPEGStaticNatives.getAvVersion0(symbolAddr[4]));
return res;
}
@@ -319,16 +328,18 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
public final List<List<String>> getToolLibNames() {
List<List<String>> libsList = new ArrayList<List<String>>();
+ // 6: util, format, codec, device, avresample, swresample
+
final List<String> avutil = new ArrayList<String>();
avutil.add("avutil"); // default
avutil.add("libavutil.so.53"); // dummy future proof
- avutil.add("libavutil.so.52"); // 9
+ avutil.add("libavutil.so.52"); // ffmpeg 1.2 + 2 / libav 9 + 10
avutil.add("libavutil.so.51"); // 0.8
avutil.add("libavutil.so.50"); // 0.7
avutil.add("avutil-53"); // dummy future proof
- avutil.add("avutil-52"); // 9
+ avutil.add("avutil-52"); // ffmpeg 1.2 + 2 / libav 9 + 10
avutil.add("avutil-51"); // 0.8
avutil.add("avutil-50"); // 0.7
libsList.add(avutil);
@@ -336,51 +347,69 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
final List<String> avformat = new ArrayList<String>();
avformat.add("avformat"); // default
- avformat.add("libavformat.so.55"); // dummy future proof
- avformat.add("libavformat.so.54"); // 9
+ avformat.add("libavformat.so.56"); // dummy future proof
+ avformat.add("libavformat.so.55"); // ffmpeg 2 / libav 10
+ avformat.add("libavformat.so.54"); // ffmpeg 1.2 / libav 9
avformat.add("libavformat.so.53"); // 0.8
avformat.add("libavformat.so.52"); // 0.7
- avformat.add("avformat-55"); // dummy future proof
- avformat.add("avformat-54"); // 9
+ avformat.add("avformat-56"); // dummy future proof
+ avformat.add("avformat-55"); // ffmpeg 2 / libav 10
+ avformat.add("avformat-54"); // ffmpeg 1.2 / libav 9
avformat.add("avformat-53"); // 0.8
- avformat.add("avformat-52"); // 0.7
+ avformat.add("avformat-52"); // 0.7
libsList.add(avformat);
final List<String> avcodec = new ArrayList<String>();
avcodec.add("avcodec"); // default
- avcodec.add("libavcodec.so.55"); // dummy future proof
- avcodec.add("libavcodec.so.54"); // 9
+ avcodec.add("libavcodec.so.56"); // dummy future proof
+ avcodec.add("libavcodec.so.55"); // ffmpeg 2/ libav 10
+ avcodec.add("libavcodec.so.54"); // ffmpeg 1.2 / libav 9
avcodec.add("libavcodec.so.53"); // 0.8
avcodec.add("libavcodec.so.52"); // 0.7
- avcodec.add("avcodec-55"); // dummy future proof
- avcodec.add("avcodec-54"); // 9
+ avcodec.add("avcodec-56"); // dummy future proof
+ avcodec.add("avcodec-55"); // ffmpeg 2/ libav 10
+ avcodec.add("avcodec-54"); // ffmpeg 1.2 / libav 9
avcodec.add("avcodec-53"); // 0.8
- avcodec.add("avcodec-52"); // 0.7
+ avcodec.add("avcodec-52"); // 0.7
libsList.add(avcodec);
final List<String> avdevice = new ArrayList<String>();
avdevice.add("avdevice"); // default
- avdevice.add("libavdevice.so.54"); // dummy future proof
- avdevice.add("libavdevice.so.53"); // 0.8 && 9
+ avdevice.add("libavdevice.so.56"); // dummy future proof
+ avdevice.add("libavdevice.so.55"); // ffmpeg 2
+ avdevice.add("libavdevice.so.54"); // ffmpeg 1.2 / libav 10
+ avdevice.add("libavdevice.so.53"); // 0.8 && libav 9
- avdevice.add("avdevice-54"); // dummy future proof
- avdevice.add("avdevice-53"); // 0.8 && 9
+ avdevice.add("avdevice-56"); // dummy future proof
+ avdevice.add("avdevice-55"); // ffmpeg 2
+ avdevice.add("avdevice-54"); // ffmpeg 1.2 / libav 10
+ avdevice.add("avdevice-53"); // 0.8 && libav 9
libsList.add(avdevice);
final List<String> avresample = new ArrayList<String>();
avresample.add("avresample"); // default
avresample.add("libavresample.so.2"); // dummy future proof
- avresample.add("libavresample.so.1"); // 9
+ avresample.add("libavresample.so.1"); // libav 9 + 10
avresample.add("avresample-2"); // dummy future proof
- avresample.add("avresample-1"); // 9
+ avresample.add("avresample-1"); // libav 9 + 10
libsList.add(avresample);
+ final List<String> swresample = new ArrayList<String>();
+ swresample.add("swresample"); // default
+
+ swresample.add("libswresample.so.1"); // dummy future proof
+ swresample.add("libswresample.so.0"); // ffmpeg 1.2 + 2.x
+
+ swresample.add("swresample-1"); // dummy future proof
+ swresample.add("swresample-0"); // ffmpeg 1.2 + 2.x
+ libsList.add(swresample);
+
return libsList;
}
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 2dd60074c..269500399 100644
--- a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java
+++ b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java
@@ -55,7 +55,7 @@ import jogamp.opengl.util.av.impl.FFMPEGNatives.SampleFormat;
/***
* Implementation utilizes <a href="http://libav.org/">Libav</a>
- * or <a href="http://ffmpeg.org/">FFmpeg</a> which is ubiquitous
+ * or <a href="http://ffmpeg.org/">FFmpeg</a> which are ubiquitous
* available and usually pre-installed on Unix platforms.
* <p>
* Due to legal reasons we cannot deploy binaries of it, which contains patented codecs.
@@ -83,6 +83,7 @@ import jogamp.opengl.util.av.impl.FFMPEGNatives.SampleFormat;
* <li>{@link PixelFormat#YUV422P}</li>
* <li>{@link PixelFormat#YUVJ422P}</li>
* <li>{@link PixelFormat#YUYV422}</li>
+ * <li>{@link PixelFormat#BGR24}</li>
* </ul>
* </p>
* <p>
@@ -104,9 +105,10 @@ import jogamp.opengl.util.av.impl.FFMPEGNatives.SampleFormat;
* <p>
* Currently we are binary compatible w/:
* <table border="1">
- * <tr><th>release</th><th>lavc</th><th>lavf</th><th>lavu</th><th>lavr</th> <th>FFMPEG* class</th></tr>
- * <tr><td>0.8</td> <td>53</td><td>53</td><td>51</td><td></td> <td>FFMPEGv08</td></tr>
- * <tr><td>9.0</td> <td>54</td><td>54</td><td>52</td><td>01</td> <td>FFMPEGv09</td></tr>
+ * <tr><th>libav / ffmpeg</th><th>lavc</th><th>lavf</th><th>lavu</th><th>lavr</th> <th>FFMPEG* class</th></tr>
+ * <tr><td>0.8</td> <td>53</td> <td>53</td> <td>51</td> <td></td> <td>FFMPEGv08</td></tr>
+ * <tr><td>9.0 / 1.2</td> <td>54</td> <td>54</td> <td>52</td> <td>01/00</td> <td>FFMPEGv09</td></tr>
+ * <tr><td>10 / 2</td> <td>55</td> <td>55</td> <td>52</td> <td>01/00</td> <td>FFMPEGv10</td></tr>
* </table>
* </p>
* <p>
@@ -122,14 +124,19 @@ import jogamp.opengl.util.av.impl.FFMPEGNatives.SampleFormat;
* <a name="todo"><h5>TODO:</h5></a>
* <p>
* <ul>
- * <li>better pts sync handling</li>
+ * <li>better audio synchronization handling? (video is synchronized)</li>
* </ul>
* </p>
*
- * <a name="libavavail"><h5>LibAV Availability</h5></a>
+ * <a name="libavavail"><h5>FFMPEG / LibAV Availability</h5></a>
* <p>
* <ul>
- * <li>Windows: http://win32.libav.org/releases/</li>
+ * <li>GNU/Linux: ffmpeg or libav are deployed in most distributions.</li>
+ * <li>Windows:
+ * <ul>
+ * <li>http://ffmpeg.zeranoe.com/builds/ (ffmpeg)</li>
+ * <li>http://win32.libav.org/releases/ (libav)</li>
+ * </ul></li>
* <li>MacOSX: http://ffmpegmac.net/</li>
* <li>OpenIndiana/Solaris:<pre>
* pkg set-publisher -p http://pkg.openindiana.org/sfe-encumbered.
@@ -148,7 +155,8 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl {
private static final int avUtilMajorVersionCC;
private static final int avFormatMajorVersionCC;
private static final int avCodecMajorVersionCC;
- private static final int avResampleMajorVersionCC;
+ private static final int avResampleMajorVersionCC;
+ private static final int swResampleMajorVersionCC;
private static final boolean available;
static {
@@ -156,24 +164,38 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl {
final boolean libAVVersionGood;
if( FFMPEGDynamicLibraryBundleInfo.libsLoaded() ) {
natives = FFMPEGDynamicLibraryBundleInfo.getNatives();
- avCodecMajorVersionCC = natives.getAvCodecMajorVersionCC0();
- avFormatMajorVersionCC = natives.getAvFormatMajorVersionCC0();
- avUtilMajorVersionCC = natives.getAvUtilMajorVersionCC0();
- avResampleMajorVersionCC = natives.getAvResampleMajorVersionCC0();
+ if( null != natives ) {
+ avCodecMajorVersionCC = natives.getAvCodecMajorVersionCC0();
+ avFormatMajorVersionCC = natives.getAvFormatMajorVersionCC0();
+ avUtilMajorVersionCC = natives.getAvUtilMajorVersionCC0();
+ avResampleMajorVersionCC = natives.getAvResampleMajorVersionCC0();
+ swResampleMajorVersionCC = natives.getSwResampleMajorVersionCC0();
+ } else {
+ avUtilMajorVersionCC = 0;
+ avFormatMajorVersionCC = 0;
+ avCodecMajorVersionCC = 0;
+ avResampleMajorVersionCC = 0;
+ swResampleMajorVersionCC = 0;
+ }
final VersionNumber avCodecVersion = FFMPEGDynamicLibraryBundleInfo.avCodecVersion;
final VersionNumber avFormatVersion = FFMPEGDynamicLibraryBundleInfo.avFormatVersion;
final VersionNumber avUtilVersion = FFMPEGDynamicLibraryBundleInfo.avUtilVersion;
- final VersionNumber avResampleVersion = FFMPEGDynamicLibraryBundleInfo.avResampleVersion;
+ final VersionNumber avResampleVersion = FFMPEGDynamicLibraryBundleInfo.avResampleVersion;
+ final boolean avResampleLoaded = FFMPEGDynamicLibraryBundleInfo.avResampleLoaded();
+ final VersionNumber swResampleVersion = FFMPEGDynamicLibraryBundleInfo.swResampleVersion;
+ final boolean swResampleLoaded = FFMPEGDynamicLibraryBundleInfo.swResampleLoaded();
System.err.println("LIB_AV Codec : "+avCodecVersion+" [cc "+avCodecMajorVersionCC+"]");
System.err.println("LIB_AV Format : "+avFormatVersion+" [cc "+avFormatMajorVersionCC+"]");
System.err.println("LIB_AV Util : "+avUtilVersion+" [cc "+avUtilMajorVersionCC+"]");
- System.err.println("LIB_AV Resample: "+FFMPEGDynamicLibraryBundleInfo.avResampleVersion+" [cc "+avResampleMajorVersionCC+", loaded "+FFMPEGDynamicLibraryBundleInfo.avResampleLoaded()+"]");
+ System.err.println("LIB_AV Resample: "+avResampleVersion+" [cc "+avResampleMajorVersionCC+", loaded "+avResampleLoaded+"]");
+ System.err.println("LIB_SW Resample: "+swResampleVersion+" [cc "+swResampleMajorVersionCC+", loaded "+swResampleLoaded+"]");
System.err.println("LIB_AV Device : [loaded "+FFMPEGDynamicLibraryBundleInfo.avDeviceLoaded()+"]");
- System.err.println("LIB_AV Class : "+natives.getClass().getSimpleName());
+ System.err.println("LIB_AV Class : "+(null!= natives ? natives.getClass().getSimpleName() : "n/a"));
libAVVersionGood = avCodecMajorVersionCC == avCodecVersion.getMajor() &&
avFormatMajorVersionCC == avFormatVersion.getMajor() &&
avUtilMajorVersionCC == avUtilVersion.getMajor() &&
- avResampleMajorVersionCC == avResampleVersion.getMajor();
+ ( !avResampleLoaded || avResampleMajorVersionCC == avResampleVersion.getMajor() ) &&
+ ( !swResampleLoaded || swResampleMajorVersionCC == swResampleVersion.getMajor() ) ;
if( !libAVVersionGood ) {
System.err.println("LIB_AV Not Matching Compile-Time / Runtime Major-Version");
}
@@ -183,6 +205,7 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl {
avFormatMajorVersionCC = 0;
avCodecMajorVersionCC = 0;
avResampleMajorVersionCC = 0;
+ swResampleMajorVersionCC = 0;
libAVVersionGood = false;
}
available = libAVGood && libAVVersionGood && null != natives ? natives.initIDs0() : false;
@@ -268,8 +291,10 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl {
System.err.println("initStream: p2 preferred "+preferredAudioFormat+", "+this);
}
- final boolean isCameraInput = null != cameraHostPart;
+ final boolean isCameraInput = null != cameraPath;
final String resStreamLocS;
+ int rw=640, rh=480, rr=15;
+ String sizes = null;
if( isCameraInput ) {
switch(Platform.OS_TYPE) {
case ANDROID:
@@ -278,10 +303,10 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl {
case HPUX:
case LINUX:
case SUNOS:
- resStreamLocS = dev_video_linux + cameraHostPart;
+ resStreamLocS = dev_video_linux + cameraPath;
break;
case WINDOWS:
- resStreamLocS = cameraHostPart;
+ resStreamLocS = cameraPath;
break;
case MACOS:
case OPENKODE:
@@ -289,13 +314,22 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl {
resStreamLocS = streamLocS; // FIXME: ??
break;
}
+ if( null != cameraProps ) {
+ sizes = cameraProps.get(CameraPropSizeS);
+ int v = getPropIntVal(cameraProps, CameraPropWidth);
+ if( v > 0 ) { rw = v; }
+ v = getPropIntVal(cameraProps, CameraPropHeight);
+ if( v > 0 ) { rh = v; }
+ v = getPropIntVal(cameraProps, CameraPropRate);
+ if( v > 0 ) { rr = v; }
+ }
} else {
resStreamLocS = streamLocS;
}
final int aMaxChannelCount = audioSink.getMaxSupportedChannels();
final int aPrefSampleRate = preferredAudioFormat.sampleRate;
// setStream(..) issues updateAttributes*(..), and defines avChosenAudioFormat, vid, aid, .. etc
- natives.setStream0(moviePtr, resStreamLocS, isCameraInput, vid, aid, aMaxChannelCount, aPrefSampleRate);
+ natives.setStream0(moviePtr, resStreamLocS, isCameraInput, vid, sizes, rw, rh, rr, aid, aMaxChannelCount, aPrefSampleRate);
}
@Override
@@ -373,11 +407,19 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl {
tf = GL2ES2.GL_RG; tif=GL2ES2.GL_RG; break;
}
case 3: tf = GL2ES2.GL_RGB; tif=GL.GL_RGB; break;
- case 4: tf = GL2ES2.GL_RGBA; tif=GL.GL_RGBA; break;
+ case 4: if( vPixelFmt == PixelFormat.BGRA ) {
+ tf = GL2ES2.GL_BGRA; tif=GL.GL_RGBA; break;
+ } else {
+ tf = GL2ES2.GL_RGBA; tif=GL.GL_RGBA; break;
+ }
default: throw new RuntimeException("Unsupported bytes-per-pixel / plane "+vBytesPerPixelPerPlane);
}
setTextureFormat(tif, tf);
setTextureType(tt);
+ if(DEBUG) {
+ System.err.println("initGL: p5: video "+vPixelFmt+", planes "+vPlanes+", bpp "+vBitsPerPixel+"/"+vBytesPerPixelPerPlane+
+ ", tex "+texWidth+"x"+texHeight+", usesTexLookupShader "+usesTexLookupShader);
+ }
}
}
@Override
@@ -470,9 +512,6 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl {
* @param planes
* @param bitsPerPixel
* @param bytesPerPixelPerPlane
- * @param lSz0
- * @param lSz1
- * @param lSz2
* @param tWd0
* @param tWd1
* @param tWd2
@@ -483,7 +522,6 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl {
* @param audioSamplesPerFrameAndChannel in audio samples per frame and channel
*/
void updateAttributes2(int vid, int pixFmt, int planes, int bitsPerPixel, int bytesPerPixelPerPlane,
- int lSz0, int lSz1, int lSz2,
int tWd0, int tWd1, int tWd2, int vW, int vH,
int aid, int audioSampleFmt, int audioSampleRate,
int audioChannels, int audioSamplesPerFrameAndChannel) {
@@ -495,7 +533,6 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl {
usesTexLookupShader = false;
texWidth = 0; texHeight = 0;
- final int[] vLinesize = { 0, 0, 0 }; // per plane
final int[] vTexWidth = { 0, 0, 0 }; // per plane
if( STREAM_ID_NONE != vid ) {
@@ -503,7 +540,6 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl {
vPlanes = planes;
vBitsPerPixel = bitsPerPixel;
vBytesPerPixelPerPlane = bytesPerPixelPerPlane;
- vLinesize[0] = lSz0; vLinesize[1] = lSz1; vLinesize[2] = lSz2;
vTexWidth[0] = tWd0; vTexWidth[1] = tWd1; vTexWidth[2] = tWd2;
switch(vPixelFmt) {
@@ -533,11 +569,12 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl {
texWidth = vTexWidth[0] + vTexWidth[1] + vTexWidth[2]; texHeight = vH;
break;
case YUYV422: // < packed YUV 4:2:2, 2x 16bpp, Y0 Cb Y1 Cr - stuffed into RGBA half width texture
+ case BGR24:
usesTexLookupShader = true;
texWidth = vTexWidth[0]; texHeight = vH;
break;
+
case RGB24:
- case BGR24:
case ARGB:
case RGBA:
case ABGR:
@@ -567,9 +604,10 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl {
System.err.println("audio: id "+aid+", fmt "+aSampleFmt+", "+avChosenAudioFormat+", aFrameSize/fc "+audioSamplesPerFrameAndChannel);
System.err.println("video: id "+vid+", fmt "+vW+"x"+vH+", "+vPixelFmt+", planes "+vPlanes+", bpp "+vBitsPerPixel+"/"+vBytesPerPixelPerPlane+", usesTexLookupShader "+usesTexLookupShader);
for(int i=0; i<3; i++) {
- System.err.println("video: "+i+": "+vTexWidth[i]+"/"+vLinesize[i]);
+ System.err.println("video: p["+i+"]: "+vTexWidth[i]);
}
System.err.println("video: total tex "+texWidth+"x"+texHeight);
+ System.err.println(this.toString());
}
}
@@ -674,6 +712,15 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl {
" return vec4(r, g, b, 1);\n"+
"}\n"
;
+ case BGR24:
+ return
+ "vec4 "+texLookupFuncName+"(in "+getTextureSampler2DType()+" image, in vec2 texCoord) {\n"+
+ " "+
+ " vec3 bgr = texture2D(image, texCoord).rgb;\n"+
+ " return vec4(bgr.b, bgr.g, bgr.r, 1);\n"+ /* just swizzle */
+ "}\n"
+ ;
+
default: // FIXME: Add more formats !
throw new InternalError("Add proper mapping of: vPixelFmt "+vPixelFmt+", usesTexLookupShader "+usesTexLookupShader);
}
diff --git a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGNatives.java b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGNatives.java
index 3ee87b5da..b919f22c7 100644
--- a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGNatives.java
+++ b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGNatives.java
@@ -27,7 +27,6 @@
*/
package jogamp.opengl.util.av.impl;
-import com.jogamp.opengl.util.av.AudioSink;
import com.jogamp.opengl.util.texture.TextureSequence.TextureFrame;
interface FFMPEGNatives {
@@ -37,6 +36,7 @@ interface FFMPEGNatives {
int getAvFormatMajorVersionCC0();
int getAvCodecMajorVersionCC0();
int getAvResampleMajorVersionCC0();
+ int getSwResampleMajorVersionCC0();
boolean initIDs0();
long createInstance0(FFMPEGMediaPlayer upstream, boolean verbose);
@@ -45,21 +45,22 @@ interface FFMPEGNatives {
/**
* Issues {@link #updateAttributes(int, int, int, int, int, int, int, float, int, int, String, String)}
* and {@link #updateAttributes2(int, int, int, int, int, int, int, int, int, int)}.
- * <p>
- * Always uses {@link AudioSink.AudioFormat}:
- * <pre>
- * [type PCM, sampleRate [10000(?)..44100..48000], sampleSize 16, channelCount 1-2, signed, littleEndian]
- * </pre>
- * </p>
*
* @param moviePtr
* @param url
* @param vid
+ * @param sizes requested video size as string, i.e. 'hd720'. May be null to favor vWidth and vHeight.
+ * @param vWidth requested video width (for camera mode)
+ * @param vHeight requested video width (for camera mode)
+ * @param vRate requested video framerate (for camera mode)
* @param aid
- * @param aPrefChannelCount
* @param aPrefSampleRate
+ * @param aPrefChannelCount
*/
- void setStream0(long moviePtr, String url, boolean isCameraInput, int vid, int aid, int aMaxChannelCount, int aPrefSampleRate);
+ void setStream0(long moviePtr, String url, boolean isCameraInput,
+ int vid, String sizes, int vWidth, int vHeight,
+ int vRate, int aid, int aMaxChannelCount, int aPrefSampleRate);
+
void setGLFuncs0(long moviePtr, long procAddrGLTexSubImage2D, long procAddrGLGetError, long procAddrGLFlush, long procAddrGLFinish);
int getVideoPTS0(long moviePtr);
diff --git a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGStaticNatives.java b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGStaticNatives.java
index 9ee0198f4..16ee2dd4b 100644
--- a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGStaticNatives.java
+++ b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGStaticNatives.java
@@ -35,8 +35,5 @@ class FFMPEGStaticNatives {
( vers >> 8 ) & 0xFF,
( vers >> 0 ) & 0xFF );
}
- static native int getAvUtilVersion0(long func);
- static native int getAvFormatVersion0(long func);
- static native int getAvCodecVersion0(long func);
- static native int getAvResampleVersion0(long func);
+ static native int getAvVersion0(long func);
}
diff --git a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGv08Natives.java b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGv08Natives.java
index 3b2567655..2a0c9dc3d 100644
--- a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGv08Natives.java
+++ b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGv08Natives.java
@@ -44,6 +44,9 @@ class FFMPEGv08Natives implements FFMPEGNatives {
public native int getAvResampleMajorVersionCC0();
@Override
+ public native int getSwResampleMajorVersionCC0();
+
+ @Override
public native boolean initIDs0();
@Override
@@ -53,7 +56,7 @@ class FFMPEGv08Natives implements FFMPEGNatives {
public native void destroyInstance0(long moviePtr);
@Override
- public native void setStream0(long moviePtr, String url, boolean isCameraInput, int vid, int aid, int aMaxChannelCount, int aPrefSampleRate);
+ public native void setStream0(long moviePtr, String url, boolean isCameraInput, int vid, String sizes, int vWidth, int vHeight, int vRate, int aid, int aMaxChannelCount, int aPrefSampleRate);
@Override
public native void setGLFuncs0(long moviePtr, long procAddrGLTexSubImage2D, long procAddrGLGetError, long procAddrGLFlush, long procAddrGLFinish);
diff --git a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGv09Natives.java b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGv09Natives.java
index 6c56d3ccb..422f1ceb0 100644
--- a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGv09Natives.java
+++ b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGv09Natives.java
@@ -44,6 +44,9 @@ class FFMPEGv09Natives implements FFMPEGNatives {
public native int getAvResampleMajorVersionCC0();
@Override
+ public native int getSwResampleMajorVersionCC0();
+
+ @Override
public native boolean initIDs0();
@Override
@@ -53,7 +56,7 @@ class FFMPEGv09Natives implements FFMPEGNatives {
public native void destroyInstance0(long moviePtr);
@Override
- public native void setStream0(long moviePtr, String url, boolean isCameraInput, int vid, int aid, int aMaxChannelCount, int aPrefSampleRate);
+ public native void setStream0(long moviePtr, String url, boolean isCameraInput, int vid, String sizes, int vWidth, int vHeight, int vRate, int aid, int aMaxChannelCount, int aPrefSampleRate);
@Override
public native void setGLFuncs0(long moviePtr, long procAddrGLTexSubImage2D, long procAddrGLGetError, long procAddrGLFlush, long procAddrGLFinish);
diff --git a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGv10Natives.java b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGv10Natives.java
new file mode 100644
index 000000000..e3007ab69
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGv10Natives.java
@@ -0,0 +1,81 @@
+/**
+ * Copyright 2013 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 jogamp.opengl.util.av.impl;
+
+class FFMPEGv10Natives implements FFMPEGNatives {
+ @Override
+ public native boolean initSymbols0(long[] symbols, int count);
+
+ @Override
+ public native int getAvUtilMajorVersionCC0();
+
+ @Override
+ public native int getAvFormatMajorVersionCC0();
+
+ @Override
+ public native int getAvCodecMajorVersionCC0();
+
+ @Override
+ public native int getAvResampleMajorVersionCC0();
+
+ @Override
+ public native int getSwResampleMajorVersionCC0();
+
+ @Override
+ public native boolean initIDs0();
+
+ @Override
+ public native long createInstance0(FFMPEGMediaPlayer upstream, boolean verbose);
+
+ @Override
+ public native void destroyInstance0(long moviePtr);
+
+ @Override
+ public native void setStream0(long moviePtr, String url, boolean isCameraInput, int vid, String sizes, int vWidth, int vHeight, int vRate, int aid, int aMaxChannelCount, int aPrefSampleRate);
+
+ @Override
+ public native void setGLFuncs0(long moviePtr, long procAddrGLTexSubImage2D, long procAddrGLGetError, long procAddrGLFlush, long procAddrGLFinish);
+
+ @Override
+ public native int getVideoPTS0(long moviePtr);
+
+ @Override
+ public native int getAudioPTS0(long moviePtr);
+
+ @Override
+ public native int readNextPacket0(long moviePtr, int texTarget, int texFmt, int texType);
+
+ @Override
+ public native int play0(long moviePtr);
+
+ @Override
+ public native int pause0(long moviePtr);
+
+ @Override
+ public native int seek0(long moviePtr, int position);
+}