From 9bf14f3c6bf98bd86913bec6e7feb54537f9b7d3 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Wed, 28 Aug 2013 12:44:06 +0200 Subject: Fix libav/ffmpeg compilation; FFMPEGMediaPlayer Enahncements (More YUV*, Use def. high camera options, cleanup symbols) - Fix libav/ffmpeg compilation - Split native GLContext code from JoglCommon - JoglCommon is required for ffmpeg_* c-compile/link - Supported versions now: - 0.8 53.53.51 - 9.0 54.54.52 - FFMPEGMediaPlayer - Update API doc, add compatibility .. etc - Pixel format conversions (via shader texture lookup func): - YUV420P, YUVJ420P - YUV422P, YUVJ422P - YUYV422 - Properly handle aid/vid - In camera mode: set high default values - TODO: Make it configurable via camera URI: - video_size - framerate - ? - FFMPEGDynamicLibraryBundleInfo - Cleanup symbols / remove unused (pre 53) - Add av_dict_* methods --- .../av/impl/FFMPEGDynamicLibraryBundleInfo.java | 38 +-- .../opengl/util/av/impl/FFMPEGMediaPlayer.java | 275 ++++++++++++++------- .../jogamp/opengl/util/av/impl/FFMPEGNatives.java | 127 ++++++---- 3 files changed, 286 insertions(+), 154 deletions(-) (limited to 'src/jogl/classes/jogamp/opengl/util') 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 040d152f5..f327cddd4 100644 --- a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java +++ b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java @@ -46,14 +46,7 @@ import com.jogamp.common.util.RunnableExecutor; import com.jogamp.common.util.VersionNumber; /** - * FIXME: We need native structure access methods to deal with API changes - * in the libav headers, which break binary compatibility! - * Currently we are binary compatible w/ [0.6 ?, ] 0.7 and 0.8 but not w/ trunk. - * - * ChangeList for trunk: - * Thu Jan 12 11:21:02 2012 a17479dfce67fbea2d0a1bf303010dce1e79059f major 53 -> 54 - * Mon Feb 27 22:40:11 2012 ee42df8a35c2b795f524c856834d0823dbd4e75d reorder AVStream and AVFormatContext - * Tue Feb 28 12:07:53 2012 322537478b63c6bc01e640643550ff539864d790 minor 1 -> 2 + * See {@link FFMPEGMediaPlayer#compatibility}. */ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo { private static final boolean DEBUG = FFMPEGMediaPlayer.DEBUG || DynamicLibraryBundleInfo.DEBUG; @@ -73,7 +66,6 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo { "avcodec_string", "avcodec_find_decoder", "avcodec_open2", // 53.6.0 (opt) - "avcodec_open", "avcodec_alloc_frame", "avcodec_get_frame_defaults", "avcodec_free_frame", // 54.28.0 (opt) @@ -85,8 +77,7 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo { "av_destruct_packet", "av_free_packet", "avcodec_decode_audio4", // 53.25.0 (opt) - "avcodec_decode_audio3", // 52.23.0 -/* 23 */ "avcodec_decode_video2", // 52.23.0 +/* 21 */ "avcodec_decode_video2", // 52.23.0 // libavutil "av_pix_fmt_descriptors", @@ -96,13 +87,16 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo { "av_get_bits_per_pixel", "av_samples_get_buffer_size", "av_get_bytes_per_sample", // 51.4.0 -/* 31 */ "av_opt_set_int", // 51.12.0 - + "av_opt_set_int", // 51.12.0 + "av_dict_get", + "av_dict_count", // 54.* (opt) + "av_dict_set", +/* 33 */ "av_dict_free", + // libavformat "avformat_alloc_context", "avformat_free_context", // 52.96.0 (opt) "avformat_close_input", // 53.17.0 (opt) - "av_close_input_file", "av_register_all", "av_find_input_format", "avformat_open_input", @@ -114,8 +108,7 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo { "av_read_pause", "avformat_network_init", // 53.13.0 (opt) "avformat_network_deinit", // 53.13.0 (opt) - "avformat_find_stream_info", // 53.3.0 (opt) -/* 48 */ "av_find_stream_info", +/* 48 */ "avformat_find_stream_info", // 53.3.0 (opt) // libavdevice /* 49 */ "avdevice_register_all", // ??? @@ -130,20 +123,15 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo { // alternate symbol names private static final String[][] altSymbolNames = { - { "avcodec_open", "avcodec_open2" }, // old, 53.6.0 - { "avcodec_decode_audio3", "avcodec_decode_audio4" }, // old, 53.25.0 - { "av_close_input_file", "avformat_close_input" }, // old, 53.17.0 - { "av_find_stream_info", "avformat_find_stream_info" }, // old, 53.3.0 + // { "av_find_stream_info", "avformat_find_stream_info" }, // old, 53.3.0 }; // optional symbol names private static final String[] optionalSymbolNames = { - "avformat_free_context", // 52.96.0 (opt) - "avformat_network_init", // 53.13.0 (opt) - "avformat_network_deinit", // 53.13.0 (opt) "avformat_seek_file", // ??? (opt) "avcodec_free_frame", // 54.28.0 (opt) "av_frame_unref", // 55.0.0 (opt) + "av_dict_count", // 54.* (opt) // libavdevice "avdevice_register_all", // 53.0.0 (opt) // libavresample @@ -377,10 +365,10 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo { avdevice.add("avdevice"); // default avdevice.add("libavdevice.so.54"); // dummy future proof - avdevice.add("libavdevice.so.53"); // 8 && 9 + avdevice.add("libavdevice.so.53"); // 0.8 && 9 avdevice.add("avdevice-54"); // dummy future proof - avdevice.add("avdevice-53"); // 8 && 9 + avdevice.add("avdevice-53"); // 0.8 && 9 libsList.add(avdevice); final List avresample = new ArrayList(); 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 952587ed9..2dd60074c 100644 --- a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java +++ b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGMediaPlayer.java @@ -38,6 +38,7 @@ import javax.media.opengl.GL2ES2; import javax.media.opengl.GLException; import com.jogamp.common.os.Platform; +import com.jogamp.common.util.VersionNumber; import com.jogamp.gluegen.runtime.ProcAddressTable; import com.jogamp.opengl.util.TimeFrameI; import com.jogamp.opengl.util.GLPixelStorageModes; @@ -55,54 +56,87 @@ import jogamp.opengl.util.av.impl.FFMPEGNatives.SampleFormat; /*** * Implementation utilizes Libav * or FFmpeg which is ubiquitous - * available and usually pre-installed on Unix platforms. Due to legal - * reasons we cannot deploy binaries of it, which contains patented codecs. + * available and usually pre-installed on Unix platforms. + *

+ * Due to legal reasons we cannot deploy binaries of it, which contains patented codecs. + *

+ *

* Besides the default BSD/Linux/.. repositories and installations, - * precompiled binaries can be found at the listed location below. + * precompiled binaries can be found at the + * listed location below. + *

+ * + *
Implementation specifics
*

- * Implements YUV420P to RGB fragment shader conversion - * and the usual packed RGB formats. * The decoded video frame is written directly into an OpenGL texture * on the GPU in it's native format. A custom fragment shader converts - * the native pixelformat to a usable RGB format if required. + * the native pixelformat to a usable RGB format if required. * Hence only 1 copy is required before bloating the picture - * from YUV to RGB, for example. + * from YUV* to RGB, for example. *

*

+ * Implements pixel format conversion to RGB via + * fragment shader texture-lookup functions: + *

    + *
  • {@link PixelFormat#YUV420P}
  • + *
  • {@link PixelFormat#YUVJ420P}
  • + *
  • {@link PixelFormat#YUV422P}
  • + *
  • {@link PixelFormat#YUVJ422P}
  • + *
  • {@link PixelFormat#YUYV422}
  • + *
+ *

+ *

+ * + *

Libav Specifics
+ *

* Utilizes a slim dynamic and native binding to the Lib_av * libraries: *

    - *
  • libavutil
  • - *
  • libavformat
  • *
  • libavcodec
  • + *
  • libavformat
  • + *
  • libavutil
  • + *
  • libavresample (opt)
  • + *
  • libavdevice (opt)
  • *
*

+ * + *
LibAV Compatibility
+ *

+ * Currently we are binary compatible w/: + * + * + * + * + *
releaselavclavflavulavr FFMPEG* class
0.8 535351 FFMPEGv08
9.0 54545201 FFMPEGv09
+ *

*

- * http://libav.org/ + * See http://upstream-tracker.org/versions/libav.html *

*

* Check tag 'FIXME: Add more planar formats !' * here and in the corresponding native code - * jogl/src/jogl/native/ffmpeg/jogamp_opengl_util_av_impl_FFMPEGMediaPlayer.c + * jogl/src/jogl/native/libav/ffmpeg_impl_template.c *

+ * + * + *
TODO:
*

- * TODO: *

    - *
  • Audio Output
  • - *
  • Off thread next frame processing using multiple target textures
  • *
  • better pts sync handling
  • - *
  • fix seek
  • *
*

- * Pre-compiled Libav / FFmpeg packages: + * + *
LibAV Availability
+ *

*

    - *
  • Windows: http://ffmpeg.zeranoe.com/builds/
  • - *
  • MacOSX: http://www.ffmpegx.com/
  • + *
  • Windows: http://win32.libav.org/releases/
  • + *
  • MacOSX: http://ffmpegmac.net/
  • *
  • OpenIndiana/Solaris:
      *       pkg set-publisher -p http://pkg.openindiana.org/sfe-encumbered.
      *       pkt install pkg:/video/ffmpeg
      *       
  • - *
+ * + *

*/ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl { @@ -122,19 +156,24 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl { final boolean libAVVersionGood; if( FFMPEGDynamicLibraryBundleInfo.libsLoaded() ) { natives = FFMPEGDynamicLibraryBundleInfo.getNatives(); - avUtilMajorVersionCC = natives.getAvUtilMajorVersionCC0(); - avFormatMajorVersionCC = natives.getAvFormatMajorVersionCC0(); avCodecMajorVersionCC = natives.getAvCodecMajorVersionCC0(); + avFormatMajorVersionCC = natives.getAvFormatMajorVersionCC0(); + avUtilMajorVersionCC = natives.getAvUtilMajorVersionCC0(); avResampleMajorVersionCC = natives.getAvResampleMajorVersionCC0(); - System.err.println("LIB_AV Util : "+FFMPEGDynamicLibraryBundleInfo.avUtilVersion+" [cc "+avUtilMajorVersionCC+"]"); - System.err.println("LIB_AV Format : "+FFMPEGDynamicLibraryBundleInfo.avFormatVersion+" [cc "+avFormatMajorVersionCC+"]"); - System.err.println("LIB_AV Codec : "+FFMPEGDynamicLibraryBundleInfo.avCodecVersion+" [cc "+avCodecMajorVersionCC+"]"); - System.err.println("LIB_AV Device : [loaded "+FFMPEGDynamicLibraryBundleInfo.avDeviceLoaded()+"]"); + final VersionNumber avCodecVersion = FFMPEGDynamicLibraryBundleInfo.avCodecVersion; + final VersionNumber avFormatVersion = FFMPEGDynamicLibraryBundleInfo.avFormatVersion; + final VersionNumber avUtilVersion = FFMPEGDynamicLibraryBundleInfo.avUtilVersion; + final VersionNumber avResampleVersion = FFMPEGDynamicLibraryBundleInfo.avResampleVersion; + 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()+"]"); - libAVVersionGood = avUtilMajorVersionCC == FFMPEGDynamicLibraryBundleInfo.avUtilVersion.getMajor() && - avFormatMajorVersionCC == FFMPEGDynamicLibraryBundleInfo.avFormatVersion.getMajor() && - avCodecMajorVersionCC == FFMPEGDynamicLibraryBundleInfo.avCodecVersion.getMajor() && - avResampleMajorVersionCC == FFMPEGDynamicLibraryBundleInfo.avResampleVersion.getMajor(); + System.err.println("LIB_AV Device : [loaded "+FFMPEGDynamicLibraryBundleInfo.avDeviceLoaded()+"]"); + System.err.println("LIB_AV Class : "+natives.getClass().getSimpleName()); + libAVVersionGood = avCodecMajorVersionCC == avCodecVersion.getMajor() && + avFormatMajorVersionCC == avFormatVersion.getMajor() && + avUtilMajorVersionCC == avUtilVersion.getMajor() && + avResampleMajorVersionCC == avResampleVersion.getMajor(); if( !libAVVersionGood ) { System.err.println("LIB_AV Not Matching Compile-Time / Runtime Major-Version"); } @@ -167,8 +206,6 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl { private int vPlanes = 0; private int vBitsPerPixel = 0; private int vBytesPerPixelPerPlane = 0; - private int[] vLinesize = { 0, 0, 0 }; // per plane - private int[] vTexWidth = { 0, 0, 0 }; // per plane private int texWidth, texHeight; // overall (stuffing planes in one texture) private String singleTexComp = "r"; private GLPixelStorageModes psm; @@ -270,7 +307,7 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl { throw new GLException("AudioSink null"); } final int audioQueueLimit; - if( null != gl ) { + if( null != gl && STREAM_ID_NONE != vid ) { final GLContextImpl ctx = (GLContextImpl)gl.getContext(); AccessController.doPrivileged(new PrivilegedAction() { public Object run() { @@ -286,12 +323,6 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl { } else { audioQueueLimit = AudioSink.DefaultQueueLimitAudioOnly; } - final float frameDuration; - if( audioSamplesPerFrameAndChannel > 0 ) { - frameDuration= avChosenAudioFormat.getSamplesDuration(audioSamplesPerFrameAndChannel); - } else { - frameDuration = AudioSink.DefaultFrameDuration; - } if(DEBUG) { System.err.println("initGL: p3 avChosen "+avChosenAudioFormat); } @@ -299,20 +330,28 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl { if( STREAM_ID_NONE == aid ) { audioSink.destroy(); audioSink = AudioSinkFactory.createNull(); - } - final boolean audioSinkOK = audioSink.init(avChosenAudioFormat, frameDuration, AudioSink.DefaultInitialQueueSize, AudioSink.DefaultQueueGrowAmount, audioQueueLimit); - if( !audioSinkOK ) { - System.err.println("AudioSink "+audioSink.getClass().getName()+" does not support "+avChosenAudioFormat+", using Null"); - audioSink.destroy(); - audioSink = AudioSinkFactory.createNull(); - audioSink.init(avChosenAudioFormat, 0, AudioSink.DefaultInitialQueueSize, AudioSink.DefaultQueueGrowAmount, audioQueueLimit); + audioSink.init(AudioSink.DefaultFormat, 0, AudioSink.DefaultInitialQueueSize, AudioSink.DefaultQueueGrowAmount, audioQueueLimit); + } else { + final float frameDuration; + if( audioSamplesPerFrameAndChannel > 0 ) { + frameDuration= avChosenAudioFormat.getSamplesDuration(audioSamplesPerFrameAndChannel); + } else { + frameDuration = AudioSink.DefaultFrameDuration; + } + final boolean audioSinkOK = audioSink.init(avChosenAudioFormat, frameDuration, AudioSink.DefaultInitialQueueSize, AudioSink.DefaultQueueGrowAmount, audioQueueLimit); + if( !audioSinkOK ) { + System.err.println("AudioSink "+audioSink.getClass().getName()+" does not support "+avChosenAudioFormat+", using Null"); + audioSink.destroy(); + audioSink = AudioSinkFactory.createNull(); + audioSink.init(avChosenAudioFormat, 0, AudioSink.DefaultInitialQueueSize, AudioSink.DefaultQueueGrowAmount, audioQueueLimit); + } } if(DEBUG) { System.err.println("initGL: p4 chosen "+avChosenAudioFormat); System.err.println("initGL: p4 chosen "+audioSink); } - if( null != gl ) { + if( null != gl && STREAM_ID_NONE != vid ) { int tf, tif=GL.GL_RGBA; // texture format and internal format int tt = GL.GL_UNSIGNED_BYTE; switch(vBytesPerPixelPerPlane) { @@ -325,7 +364,7 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl { tf = GL2ES2.GL_ALPHA; tif=GL2ES2.GL_ALPHA; singleTexComp = "a"; } break; - + case 2: if( vPixelFmt == PixelFormat.YUYV422 ) { // YUYV422: // < packed YUV 4:2:2, 2x 16bpp, Y0 Cb Y1 Cr // Stuffed into RGBA half width texture @@ -426,6 +465,7 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl { /** * Native callback + * @param vid * @param pixFmt * @param planes * @param bitsPerPixel @@ -436,58 +476,96 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl { * @param tWd0 * @param tWd1 * @param tWd2 + * @param aid * @param audioSampleFmt * @param audioSampleRate * @param audioChannels * @param audioSamplesPerFrameAndChannel in audio samples per frame and channel */ - void updateAttributes2(int pixFmt, int planes, int bitsPerPixel, int bytesPerPixelPerPlane, + 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 audioSampleFmt, int audioSampleRate, + int aid, int audioSampleFmt, int audioSampleRate, int audioChannels, int audioSamplesPerFrameAndChannel) { - vPixelFmt = PixelFormat.valueOf(pixFmt); - vPlanes = planes; - vBitsPerPixel = bitsPerPixel; - vBytesPerPixelPerPlane = bytesPerPixelPerPlane; - vLinesize[0] = lSz0; vLinesize[1] = lSz1; vLinesize[2] = lSz2; - vTexWidth[0] = tWd0; vTexWidth[1] = tWd1; vTexWidth[2] = tWd2; + // defaults .. + vPixelFmt = null; + vPlanes = 0; + vBitsPerPixel = 0; + vBytesPerPixelPerPlane = 0; + usesTexLookupShader = false; + texWidth = 0; texHeight = 0; - switch(vPixelFmt) { - case YUV420P: // < planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples) - usesTexLookupShader = true; - // YUV420P: Adding U+V on right side of fixed height texture, - // since width is already aligned by decoder. - // Y=w*h, Y=w/2*h/2, U=w/2*h/2 - // w*h + 2 ( w/2 * h/2 ) - // w*h + w*h/2 - // 2*w/2 * h - texWidth = vTexWidth[0] + vTexWidth[1]; texHeight = vH; - break; - case YUYV422: // < packed YUV 4:2:2, 2x 16bpp, Y0 Cb Y1 Cr - stuffed into RGBA half width texture - usesTexLookupShader = true; - texWidth = vTexWidth[0]; texHeight = vH; - break; - case RGB24: - case BGR24: - case ARGB: - case RGBA: - case ABGR: - case BGRA: - usesTexLookupShader = false; - texWidth = vTexWidth[0]; texHeight = vH; - break; - default: // FIXME: Add more formats ! - throw new RuntimeException("Unsupported pixelformat: "+vPixelFmt); + final int[] vLinesize = { 0, 0, 0 }; // per plane + final int[] vTexWidth = { 0, 0, 0 }; // per plane + + if( STREAM_ID_NONE != vid ) { + vPixelFmt = PixelFormat.valueOf(pixFmt); + 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) { + case YUVJ420P: + case YUV420P: // < planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples) + usesTexLookupShader = true; + // YUV420P: Adding U+V on right side of fixed height texture, + // since width is already aligned by decoder. + // Splitting texture to 4 quadrants: + // Y covers left top/low quadrant + // U on top-right quadrant. + // V on low-right quadrant. + // Y=w*h, U=w/2*h/2, V=w/2*h/2 + // w*h + 2 ( w/2 * h/2 ) + // w*h + w*h/2 + texWidth = vTexWidth[0] + vTexWidth[1]; texHeight = vH; + break; + case YUVJ422P: + case YUV422P: + usesTexLookupShader = true; + // YUV422P: Adding U+V on right side of fixed height texture, + // since width is already aligned by decoder. + // Splitting texture to 4 columns + // Y covers columns 1+2 + // U covers columns 3 + // V covers columns 4 + 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 + usesTexLookupShader = true; + texWidth = vTexWidth[0]; texHeight = vH; + break; + case RGB24: + case BGR24: + case ARGB: + case RGBA: + case ABGR: + case BGRA: + usesTexLookupShader = false; + texWidth = vTexWidth[0]; texHeight = vH; + break; + default: // FIXME: Add more formats ! + throw new RuntimeException("Unsupported pixelformat: "+vPixelFmt); + } + } + + // defaults .. + final SampleFormat aSampleFmt; + avChosenAudioFormat = null;; + this.audioSamplesPerFrameAndChannel = 0; + + if( STREAM_ID_NONE != aid ) { + aSampleFmt = SampleFormat.valueOf(audioSampleFmt); + avChosenAudioFormat = avAudioFormat2Local(aSampleFmt, audioSampleRate, audioChannels); + this.audioSamplesPerFrameAndChannel = audioSamplesPerFrameAndChannel; + } else { + aSampleFmt = null; } - final SampleFormat aSampleFmt = SampleFormat.valueOf(audioSampleFmt); - avChosenAudioFormat = avAudioFormat2Local(aSampleFmt, audioSampleRate, audioChannels); - - this.audioSamplesPerFrameAndChannel = audioSamplesPerFrameAndChannel; if(DEBUG) { - System.err.println("audio: fmt "+aSampleFmt+", "+avChosenAudioFormat+", aFrameSize/fc "+audioSamplesPerFrameAndChannel); - System.err.println("video: fmt "+vW+"x"+vH+", "+vPixelFmt+", planes "+vPlanes+", bpp "+vBitsPerPixel+"/"+vBytesPerPixelPerPlane+", usesTexLookupShader "+usesTexLookupShader); + 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]); } @@ -532,6 +610,7 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl { } final float tc_w_1 = (float)getWidth() / (float)texWidth; switch(vPixelFmt) { + case YUVJ420P: case YUV420P: // < planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples) return "vec4 "+texLookupFuncName+"(in "+getTextureSampler2DType()+" image, in vec2 texCoord) {\n"+ @@ -551,6 +630,28 @@ public class FFMPEGMediaPlayer extends GLMediaPlayerImpl { " return vec4(r, g, b, 1);\n"+ "}\n" ; + + case YUVJ422P: + case YUV422P: ///< planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples) + return + "vec4 "+texLookupFuncName+"(in "+getTextureSampler2DType()+" image, in vec2 texCoord) {\n"+ + " vec2 u_off = vec2("+tc_w_1+" , 0.0);\n"+ + " vec2 v_off = vec2("+tc_w_1+" * 1.5, 0.0);\n"+ + " vec2 tc_halfw = vec2(texCoord.x*0.5, texCoord.y);\n"+ + " float y,u,v,r,g,b;\n"+ + " y = texture2D(image, texCoord)."+singleTexComp+";\n"+ + " u = texture2D(image, u_off+tc_halfw)."+singleTexComp+";\n"+ + " v = texture2D(image, v_off+tc_halfw)."+singleTexComp+";\n"+ + " y = 1.1643*(y-0.0625);\n"+ + " u = u-0.5;\n"+ + " v = v-0.5;\n"+ + " r = y+1.5958*v;\n"+ + " g = y-0.39173*u-0.81290*v;\n"+ + " b = y+2.017*u;\n"+ + " return vec4(r, g, b, 1);\n"+ + "}\n" + ; + case YUYV422: // < packed YUV 4:2:2, 2 x 16bpp, [Y0 Cb] [Y1 Cr] // Stuffed into RGBA half width texture return 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 9dd1ac74a..3ee87b5da 100644 --- a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGNatives.java +++ b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGNatives.java @@ -105,51 +105,94 @@ interface FFMPEGNatives { /** FFMPEG/libAV Pixel Format */ public static enum PixelFormat { // NONE= -1, - YUV420P, ///< planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples) - YUYV422, ///< packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr - RGB24, ///< packed RGB 8:8:8, 24bpp, RGBRGB... - BGR24, ///< packed RGB 8:8:8, 24bpp, BGRBGR... - YUV422P, ///< planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples) - YUV444P, ///< planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples) - YUV410P, ///< planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples) - YUV411P, ///< planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) - GRAY8, ///< Y , 8bpp - MONOWHITE, ///< Y , 1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb - MONOBLACK, ///< Y , 1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb - PAL8, ///< 8 bit with RGB32 palette - YUVJ420P, ///< planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of YUV420P and setting color_range - YUVJ422P, ///< planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of YUV422P and setting color_range - YUVJ444P, ///< planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of YUV444P and setting color_range - XVMC_MPEG2_MC,///< XVideo Motion Acceleration via common packet passing + /** planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples) */ + YUV420P, + /** packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr ( sharing Cb and Cr w/ 2 pixels )*/ + YUYV422, + /** packed RGB 8:8:8, 24bpp, RGBRGB... */ + RGB24, + /** packed RGB 8:8:8, 24bpp, BGRBGR... */ + BGR24, + /** planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples) */ + YUV422P, + /** planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples) */ + YUV444P, + /** planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples) */ + YUV410P, + /** planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) */ + YUV411P, + /** Y, 8bpp */ + GRAY8, + /** Y, 1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb */ + MONOWHITE, + /** Y, 1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb */ + MONOBLACK, + /** 8 bit with RGB32 palette */ + PAL8, + /** planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of YUV420P and setting color_range */ + YUVJ420P, + /** planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of YUV422P and setting color_range */ + YUVJ422P, + /** planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of YUV444P and setting color_range */ + YUVJ444P, + /** XVideo Motion Acceleration via common packet passing */ + XVMC_MPEG2_MC, + /** */ XVMC_MPEG2_IDCT, - UYVY422, ///< packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1 - UYYVYY411, ///< packed YUV 4:1:1, 12bpp, Cb Y0 Y1 Cr Y2 Y3 - BGR8, ///< packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb) - BGR4, ///< packed RGB 1:2:1 bitstream, 4bpp, (msb)1B 2G 1R(lsb), a byte contains two pixels, the first pixel in the byte is the one composed by the 4 msb bits - BGR4_BYTE, ///< packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb) - RGB8, ///< packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb) - RGB4, ///< packed RGB 1:2:1 bitstream, 4bpp, (msb)1R 2G 1B(lsb), a byte contains two pixels, the first pixel in the byte is the one composed by the 4 msb bits - RGB4_BYTE, ///< packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb) - NV12, ///< planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (first byte U and the following byte V) - NV21, ///< as above, but U and V bytes are swapped + /** packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1 */ + UYVY422, + /** packed YUV 4:1:1, 12bpp, Cb Y0 Y1 Cr Y2 Y3 */ + UYYVYY411, + /** packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb) */ + BGR8, + /** packed RGB 1:2:1 bitstream, 4bpp, (msb)1B 2G 1R(lsb), a byte contains two pixels, the first pixel in the byte is the one composed by the 4 msb bits */ + BGR4, + /** packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb) */ + BGR4_BYTE, + /** packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb) */ + RGB8, + /** packed RGB 1:2:1 bitstream, 4bpp, (msb)1R 2G 1B(lsb), a byte contains two pixels, the first pixel in the byte is the one composed by the 4 msb bits */ + RGB4, + /** packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb) */ + RGB4_BYTE, + /** planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (first byte U and the following byte V) */ + NV12, + /** as above, but U and V bytes are swapped */ + NV21, - ARGB, ///< packed ARGB 8:8:8:8, 32bpp, ARGBARGB... - RGBA, ///< packed RGBA 8:8:8:8, 32bpp, RGBARGBA... - ABGR, ///< packed ABGR 8:8:8:8, 32bpp, ABGRABGR... - BGRA, ///< packed BGRA 8:8:8:8, 32bpp, BGRABGRA... + /** packed ARGB 8:8:8:8, 32bpp, ARGBARGB... */ + ARGB, + /** packed RGBA 8:8:8:8, 32bpp, RGBARGBA... */ + RGBA, + /** packed ABGR 8:8:8:8, 32bpp, ABGRABGR... */ + ABGR, + /** packed BGRA 8:8:8:8, 32bpp, BGRABGRA... */ + BGRA, - GRAY16BE, ///< Y , 16bpp, big-endian - GRAY16LE, ///< Y , 16bpp, little-endian - YUV440P, ///< planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples) - YUVJ440P, ///< planar YUV 4:4:0 full scale (JPEG), deprecated in favor of YUV440P and setting color_range - YUVA420P, ///< planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples) - VDPAU_H264,///< H.264 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers - VDPAU_MPEG1,///< MPEG-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers - VDPAU_MPEG2,///< MPEG-2 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers - VDPAU_WMV3,///< WMV3 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers - VDPAU_VC1, ///< VC-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers - RGB48BE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as big-endian - RGB48LE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as little-endian + /** Y, 16bpp, big-endian */ + GRAY16BE, + /** Y , 16bpp, little-endian */ + GRAY16LE, + /** planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples) */ + YUV440P, + /** planar YUV 4:4:0 full scale (JPEG), deprecated in favor of YUV440P and setting color_range */ + YUVJ440P, + /** planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples) */ + YUVA420P, + /** H.264 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers */ + VDPAU_H264, + /** MPEG-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers */ + VDPAU_MPEG1, + /** MPEG-2 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers */ + VDPAU_MPEG2, + /** WMV3 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers */ + VDPAU_WMV3, + /** VC-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers */ + VDPAU_VC1, + /** packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as big-endian */ + RGB48BE, + /** packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as little-endian */ + RGB48LE, RGB565BE, ///< packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), big-endian RGB565LE, ///< packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), little-endian -- cgit v1.2.3