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;