diff options
author | Sven Gothel <[email protected]> | 2013-08-29 22:46:57 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2013-08-29 22:46:57 +0200 |
commit | eca6a5cb1e2beda84dfbafc31ed225e272f4f3fb (patch) | |
tree | c77750eac39a611bbc46b77f64e5ae5c123e9427 /src/jogl/classes | |
parent | 9bf14f3c6bf98bd86913bec6e7feb54537f9b7d3 (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')
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); +} |