diff --git a/CHANGELOG.md b/CHANGELOG.md index bd8233dd..b1080c16 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,8 @@ + * Add `videoCodec`, `videoBitrate`, `audioCodec`, and `audioBitrate` properties to `FrameGrabber` + * Work around `avcodec` and `avdevice` not loading properly for `FFmpegFrameGrabber` and `FFmpegFrameRecorder` ([issue #24](https://github.com/bytedeco/javacv/issues/24)) + * Do key frame detection in `FFmpegFrameRecorder` based on `AVPacket`, not `AVPicture` ([pull #20](https://github.com/bytedeco/javacv/pull/20)) + ### July 27, 2014 version 0.9 * Remove `platform` property from `pom.xml`, replaced with the `platform.dependency` one in JavaCPP Presets ([issue #10](https://github.com/bytedeco/javacv/issues/10)) * Add new `RLSA` sample, thanks to Nicholas Woodward ([issue #469](http://code.google.com/p/javacv/issues/detail?id=469)) diff --git a/pom.xml b/pom.xml index 6083b4de..d54402fb 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 org.bytedeco javacv - 0.9 + 0.9.1-SNAPSHOT jar JavaCV @@ -48,7 +48,7 @@ UTF-8 yyyyMMddhhmm - ${project.version} + 0.9 **/Mark*.java diff --git a/src/main/java/org/bytedeco/javacv/FFmpegFrameGrabber.java b/src/main/java/org/bytedeco/javacv/FFmpegFrameGrabber.java index 725cbd1d..3a2dd1d7 100644 --- a/src/main/java/org/bytedeco/javacv/FFmpegFrameGrabber.java +++ b/src/main/java/org/bytedeco/javacv/FFmpegFrameGrabber.java @@ -84,10 +84,18 @@ public static void tryLoad() throws Exception { } else { try { Loader.load(org.bytedeco.javacpp.avutil.class); + Loader.load(org.bytedeco.javacpp.swresample.class); Loader.load(org.bytedeco.javacpp.avcodec.class); Loader.load(org.bytedeco.javacpp.avformat.class); - Loader.load(org.bytedeco.javacpp.avdevice.class); Loader.load(org.bytedeco.javacpp.swscale.class); + + // Register all formats and codecs + avcodec_register_all(); + av_register_all(); + avformat_network_init(); + + Loader.load(org.bytedeco.javacpp.avdevice.class); + avdevice_register_all(); } catch (Throwable t) { if (t instanceof Exception) { throw loadingException = (Exception)t; @@ -99,11 +107,9 @@ public static void tryLoad() throws Exception { } static { - // Register all formats and codecs - avcodec_register_all(); - avdevice_register_all(); - av_register_all(); - avformat_network_init(); + try { + tryLoad(); + } catch (Exception ex) { } } public FFmpegFrameGrabber(File file) { @@ -242,6 +248,14 @@ public void releaseUnsafe() throws Exception { } } + @Override public int getVideoCodec() { + return video_c == null ? super.getVideoCodec() : video_c.codec_id(); + } + + @Override public int getVideoBitrate() { + return video_c == null ? super.getVideoBitrate() : video_c.bit_rate(); + } + @Override public double getFrameRate() { if (video_st == null) { return super.getFrameRate(); @@ -251,6 +265,14 @@ public void releaseUnsafe() throws Exception { } } + @Override public int getAudioCodec() { + return audio_c == null ? super.getAudioCodec() : audio_c.codec_id(); + } + + @Override public int getAudioBitrate() { + return audio_c == null ? super.getAudioBitrate() : audio_c.bit_rate(); + } + @Override public int getSampleFormat() { return audio_c == null ? super.getSampleFormat() : audio_c.sample_fmt(); } diff --git a/src/main/java/org/bytedeco/javacv/FFmpegFrameRecorder.java b/src/main/java/org/bytedeco/javacv/FFmpegFrameRecorder.java index 005d19c6..1211a6cf 100644 --- a/src/main/java/org/bytedeco/javacv/FFmpegFrameRecorder.java +++ b/src/main/java/org/bytedeco/javacv/FFmpegFrameRecorder.java @@ -88,9 +88,14 @@ public static void tryLoad() throws Exception { } else { try { Loader.load(org.bytedeco.javacpp.avutil.class); + Loader.load(org.bytedeco.javacpp.swresample.class); Loader.load(org.bytedeco.javacpp.avcodec.class); Loader.load(org.bytedeco.javacpp.avformat.class); Loader.load(org.bytedeco.javacpp.swscale.class); + + /* initialize libavcodec, and register all codecs and formats */ + av_register_all(); + avformat_network_init(); } catch (Throwable t) { if (t instanceof Exception) { throw loadingException = (Exception)t; @@ -102,9 +107,9 @@ public static void tryLoad() throws Exception { } static { - /* initialize libavcodec, and register all codecs and formats */ - av_register_all(); - avformat_network_init(); + try { + tryLoad(); + } catch (Exception ex) { } } public FFmpegFrameRecorder(File file, int audioChannels) { diff --git a/src/main/java/org/bytedeco/javacv/FrameGrabber.java b/src/main/java/org/bytedeco/javacv/FrameGrabber.java index 28fa8b20..3870aa99 100644 --- a/src/main/java/org/bytedeco/javacv/FrameGrabber.java +++ b/src/main/java/org/bytedeco/javacv/FrameGrabber.java @@ -41,7 +41,7 @@ public abstract class FrameGrabber { public static final List list = new LinkedList(Arrays.asList(new String[] { - "DC1394", "FlyCapture", "OpenKinect", "PS3Eye", "VideoInput", "OpenCV", "FFmpeg" })); + "DC1394", "FlyCapture", "OpenKinect", "PS3Eye", "VideoInput", "OpenCV", "FFmpeg", "IPCamera" })); public static void init() { for (String name : list) { try { @@ -169,9 +169,9 @@ public static enum ImageMode { protected int imageWidth = 0, imageHeight = 0, audioChannels = 0; protected ImageMode imageMode = ImageMode.COLOR; protected long sensorPattern = -1L; - protected int pixelFormat = -1; + protected int pixelFormat = -1, videoCodec, videoBitrate = 0; protected double frameRate = 0; - protected int sampleFormat = 0, sampleRate = 0; + protected int sampleFormat = 0, audioCodec, audioBitrate = 0, sampleRate = 0; protected boolean triggerMode = false; protected int bpp = 0; protected int timeout = 10000; @@ -230,6 +230,20 @@ public void setPixelFormat(int pixelFormat) { this.pixelFormat = pixelFormat; } + public int getVideoCodec() { + return videoCodec; + } + public void setVideoCodec(int videoCodec) { + this.videoCodec = videoCodec; + } + + public int getVideoBitrate() { + return videoBitrate; + } + public void setVideoBitrate(int videoBitrate) { + this.videoBitrate = videoBitrate; + } + public double getFrameRate() { return frameRate; } @@ -237,6 +251,20 @@ public void setFrameRate(double frameRate) { this.frameRate = frameRate; } + public int getAudioCodec() { + return audioCodec; + } + public void setAudioCodec(int audioCodec) { + this.audioCodec = audioCodec; + } + + public int getAudioBitrate() { + return audioBitrate; + } + public void setAudioBitrate(int audioBitrate) { + this.audioBitrate = audioBitrate; + } + public int getSampleFormat() { return sampleFormat; } diff --git a/src/main/java/org/bytedeco/javacv/IPCameraFrameGrabber.java b/src/main/java/org/bytedeco/javacv/IPCameraFrameGrabber.java index e335138d..159026f5 100644 --- a/src/main/java/org/bytedeco/javacv/IPCameraFrameGrabber.java +++ b/src/main/java/org/bytedeco/javacv/IPCameraFrameGrabber.java @@ -30,9 +30,9 @@ import java.net.URLConnection; import java.util.List; import java.util.Map; -import org.bytedeco.javacpp.BytePointer; - import javax.imageio.ImageIO; +import org.bytedeco.javacpp.BytePointer; +import org.bytedeco.javacpp.Loader; import static org.bytedeco.javacpp.opencv_core.*; import static org.bytedeco.javacpp.opencv_highgui.*; @@ -46,6 +46,19 @@ public class IPCameraFrameGrabber extends FrameGrabber { * cam http://192.168.0.57:8080/videofeed */ + private static Exception loadingException = null; + public static void tryLoad() throws Exception { + if (loadingException != null) { + throw loadingException; + } else { + try { + Loader.load(org.bytedeco.javacpp.opencv_highgui.class); + } catch (Throwable t) { + throw loadingException = new Exception("Failed to load " + IPCameraFrameGrabber.class, t); + } + } + } + private URL url; private URLConnection connection; private InputStream input;