/*
* Copyright (C) 2011-2013 Samuel Audet
*
* Licensed either under the Apache License, Version 2.0, or (at your option)
* under the terms of the GNU General Public License as published by
* the Free Software Foundation (subject to the "Classpath" exception),
* either version 2, or any later version (collectively, the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.gnu.org/licenses/
* http://www.gnu.org/software/classpath/license.html
*
* or as provided in the LICENSE.txt file that accompanied this code.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.bytedeco.javacv;
import java.io.File;
import org.bytedeco.javacpp.BytePointer;
import org.bytedeco.javacpp.Loader;
import static org.bytedeco.javacpp.opencv_core.*;
import static org.bytedeco.javacpp.opencv_imgproc.*;
import static org.bytedeco.javacpp.videoInputLib.*;
/**
*
* @author Samuel Audet
*/
public class VideoInputFrameGrabber extends FrameGrabber {
public static String[] getDeviceDescriptions() throws Exception {
tryLoad();
int count = videoInput.listDevices();
String[] descriptions = new String[count];
for (int i = 0; i < descriptions.length; i++) {
descriptions[i] = videoInput.getDeviceName(i).getString();
}
return descriptions;
}
public static VideoInputFrameGrabber createDefault(File deviceFile) throws Exception { throw new Exception(VideoInputFrameGrabber.class + " does not support device files."); }
public static VideoInputFrameGrabber createDefault(String devicePath) throws Exception { throw new Exception(VideoInputFrameGrabber.class + " does not support device paths."); }
public static VideoInputFrameGrabber createDefault(int deviceNumber) throws Exception { return new VideoInputFrameGrabber(deviceNumber); }
private static Exception loadingException = null;
public static void tryLoad() throws Exception {
if (loadingException != null) {
throw loadingException;
} else {
try {
Loader.load(org.bytedeco.javacpp.videoInputLib.class);
} catch (Throwable t) {
throw loadingException = new Exception("Failed to load " + VideoInputFrameGrabber.class, t);
}
}
}
public VideoInputFrameGrabber(int deviceNumber) {
this.deviceNumber = deviceNumber;
}
public void release() throws Exception {
stop();
}
@Override protected void finalize() throws Throwable {
super.finalize();
release();
}
private int deviceNumber = 0;
private videoInput myVideoInput = null;
private IplImage bgrImage = null, grayImage = null;
private BytePointer bgrImageData = null;
private FrameConverter converter = new OpenCVFrameConverter.ToIplImage();
@Override public double getGamma() {
// default to a gamma of 2.2 for cheap Webcams, DV cameras, etc.
if (gamma == 0.0) {
return 2.2;
} else {
return gamma;
}
}
@Override public int getImageWidth() {
return myVideoInput == null ? super.getImageWidth() : myVideoInput.getWidth(deviceNumber);
}
@Override public int getImageHeight() {
return myVideoInput == null ? super.getImageHeight() : myVideoInput.getHeight(deviceNumber);
}
public void start() throws Exception {
start(-1);
}
public void start(int connection) throws Exception {
myVideoInput = new videoInput();
if (frameRate > 0) {
myVideoInput.setIdealFramerate(deviceNumber, (int)frameRate);
}
if (!myVideoInput.setupDevice(deviceNumber, imageWidth > 0 ? imageWidth : 640,
imageHeight > 0 ? imageHeight : 480, connection)) {
myVideoInput = null;
throw new Exception("videoInput.setupDevice() Error: Could not setup device.");
}
if (format != null && format.length() > 0) {
int f = format.equals("VI_NTSC_M") ? VI_NTSC_M :
format.equals("VI_PAL_B") ? VI_PAL_B :
format.equals("VI_PAL_D") ? VI_PAL_D :
format.equals("VI_PAL_G") ? VI_PAL_G :
format.equals("VI_PAL_H") ? VI_PAL_H :
format.equals("VI_PAL_I") ? VI_PAL_I :
format.equals("VI_PAL_M") ? VI_PAL_M :
format.equals("VI_PAL_N") ? VI_PAL_N :
format.equals("VI_PAL_NC") ? VI_PAL_NC :
format.equals("VI_SECAM_B") ? VI_SECAM_B :
format.equals("VI_SECAM_D") ? VI_SECAM_D :
format.equals("VI_SECAM_G") ? VI_SECAM_G :
format.equals("VI_SECAM_H") ? VI_SECAM_H :
format.equals("VI_SECAM_K") ? VI_SECAM_K :
format.equals("VI_SECAM_K1") ? VI_SECAM_K1 :
format.equals("VI_SECAM_L") ? VI_SECAM_L :
format.equals("VI_NTSC_M_J") ? VI_NTSC_M_J :
format.equals("VI_NTSC_433") ? VI_NTSC_433 : -1;
if (f >= 0 && !myVideoInput.setFormat(deviceNumber, f)) {
throw new Exception("videoInput.setFormat() Error: Could not set format " + format + ".");
}
}
}
public void stop() throws Exception {
if (myVideoInput != null) {
myVideoInput.stopDevice(deviceNumber);
myVideoInput = null;
}
}
public void trigger() throws Exception {
if (myVideoInput == null) {
throw new Exception("videoInput is null. (Has start() been called?)");
}
int w = myVideoInput.getWidth(deviceNumber), h = myVideoInput.getHeight(deviceNumber);
if (bgrImage == null || bgrImage.width() != w || bgrImage.height() != h) {
bgrImage = IplImage.create(w, h, IPL_DEPTH_8U, 3);
bgrImageData = bgrImage.imageData();
}
for (int i = 0; i < numBuffers+1; i++) {
myVideoInput.getPixels(deviceNumber, bgrImageData, false, true);
}
}
public Frame grab() throws Exception {
if (myVideoInput == null) {
throw new Exception("videoInput is null. (Has start() been called?)");
}
int w = myVideoInput.getWidth(deviceNumber), h = myVideoInput.getHeight(deviceNumber);
if (bgrImage == null || bgrImage.width() != w || bgrImage.height() != h) {
bgrImage = IplImage.create(w, h, IPL_DEPTH_8U, 3);
bgrImageData = bgrImage.imageData();
}
if (!myVideoInput.getPixels(deviceNumber, bgrImageData, false, true)) {
throw new Exception("videoInput.getPixels() Error: Could not get pixels.");
}
timestamp = System.nanoTime()/1000;
if (imageMode == ImageMode.GRAY) {
if (grayImage == null) {
grayImage = IplImage.create(w, h, IPL_DEPTH_8U, 1);
}
cvCvtColor(bgrImage, grayImage, CV_BGR2GRAY);
return converter.convert(grayImage);
} else {
return converter.convert(bgrImage);
}
}
}