├── .gitignore ├── CREDITS ├── src └── main │ ├── resources │ └── META-INF │ │ └── native │ │ ├── linux-64 │ │ ├── libv4l4j.so │ │ └── libvideo.so │ │ └── linux-armhf │ │ ├── libv4l4j.so │ │ └── libvideo.so │ └── java │ ├── au │ └── edu │ │ └── jcu │ │ └── v4l4j │ │ ├── exceptions │ │ ├── package-info.java │ │ ├── V4L4JException.java │ │ ├── InvalidValue.java │ │ ├── UnsupportedMethod.java │ │ ├── ControlException.java │ │ ├── CaptureChannelException.java │ │ ├── JNIException.java │ │ ├── VideoStandardException.java │ │ ├── ImageDimensionsException.java │ │ ├── NoTunerException.java │ │ ├── ImageFormatException.java │ │ ├── ReleaseException.java │ │ ├── StateException.java │ │ └── InitialisationException.java │ │ ├── V4L4JDataBuffer.java │ │ ├── V4L4JRaster.java │ │ ├── CaptureCallback.java │ │ ├── JPEGVideoFrame.java │ │ ├── UncompressedVideoFrame.java │ │ ├── TunerList.java │ │ ├── TunerInfo.java │ │ ├── RawFrameGrabber.java │ │ ├── ControlList.java │ │ ├── ImageFormat.java │ │ ├── Tuner.java │ │ ├── PushSource.java │ │ ├── InputInfo.java │ │ ├── YUVFrameGrabber.java │ │ ├── YVUFrameGrabber.java │ │ ├── BGRFrameGrabber.java │ │ ├── RGBFrameGrabber.java │ │ ├── package-info.java │ │ ├── BaseVideoFrame.java │ │ ├── VideoFrame.java │ │ ├── JPEGFrameGrabber.java │ │ ├── DeviceInfo.java │ │ ├── V4L4JConstants.java │ │ ├── FrameInterval.java │ │ ├── FrameGrabber.java │ │ └── ResolutionInfo.java │ └── com │ └── github │ └── sarxos │ └── v4l4j │ ├── V4L4J.java │ └── NativeUtils.java ├── import.sh ├── README.md ├── pom.xml └── svn.log /.gitignore: -------------------------------------------------------------------------------- 1 | .project 2 | .classpath 3 | .settings 4 | target 5 | pom.xml.releaseBackup 6 | release.properties 7 | 8 | -------------------------------------------------------------------------------- /CREDITS: -------------------------------------------------------------------------------- 1 | Thanks to all v4l4j users for spending time testing, reporting bugs and 2 | successes, submitting examples and improving the code. 3 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/native/linux-64/libv4l4j.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarxos/v4l4j/HEAD/src/main/resources/META-INF/native/linux-64/libv4l4j.so -------------------------------------------------------------------------------- /src/main/resources/META-INF/native/linux-64/libvideo.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarxos/v4l4j/HEAD/src/main/resources/META-INF/native/linux-64/libvideo.so -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/exceptions/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | *

Video4Linux4java exception Package

3 | */ 4 | package au.edu.jcu.v4l4j.exceptions; 5 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/native/linux-armhf/libv4l4j.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarxos/v4l4j/HEAD/src/main/resources/META-INF/native/linux-armhf/libv4l4j.so -------------------------------------------------------------------------------- /src/main/resources/META-INF/native/linux-armhf/libvideo.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarxos/v4l4j/HEAD/src/main/resources/META-INF/native/linux-armhf/libvideo.so -------------------------------------------------------------------------------- /import.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | 3 | TRUNK="$(pwd)/v4l4j-trunk" 4 | 5 | svn co http://v4l4j.googlecode.com/svn/v4l4j/trunk $TRUNK > svn.log 6 | 7 | rm -rf src/main/java/au 8 | 9 | cp $TRUNK/COPYING . 10 | cp $TRUNK/CREDITS . 11 | cp -r $TRUNK/src/au src/main/java 12 | 13 | rm -rf src/main/java/au/edu/jcu/v4l4j/examples 14 | rm -rf src/main/java/au/edu/jcu/v4l4j/test 15 | rm -rf $TRUNK 16 | 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # V4L4J 2 | 3 | This is mavenized and customized fork of original [V4L4J](http://code.google.com/p/v4l4j) by Gilles Gigan. It contains only Java source code (no natives) and *.so objects precompiled for several architectures: 4 | 5 | * Linux 64-bit, 6 | * Linux ARM (hard float). 7 | 8 | In case you need more architectures please compile binaries by following [this](https://code.google.com/p/v4l4j/wiki/SourceInstall) procedure. 9 | 10 | Source revision [r507](http://code.google.com/p/v4l4j/source/detail?r=507). 11 | 12 | ## Maven 13 | 14 | The artifact is available in Maven Central: 15 | 16 | ```xml 17 | 18 | com.github.sarxos 19 | v4l4j 20 | 0.9.1-r507 21 | 22 | ``` 23 | 24 | ## License 25 | 26 | The code is distributed under the terms of GNU GPL v3. 27 | -------------------------------------------------------------------------------- /src/main/java/com/github/sarxos/v4l4j/V4L4J.java: -------------------------------------------------------------------------------- 1 | package com.github.sarxos.v4l4j; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | 6 | 7 | /** 8 | * 9 | * @author sarxos 10 | * 11 | */ 12 | public class V4L4J { 13 | 14 | private static String getArch() { 15 | 16 | String arch = System.getProperty("os.arch"); 17 | String dataModel = System.getProperty("sun.arch.data.model", System.getProperty("com.ibm.vm.bitmode")); 18 | String bits; 19 | 20 | if (isArm()) { 21 | return "arm" + getFloat(); 22 | } else { 23 | 24 | if ("32".equals(dataModel)) { 25 | bits = "32"; 26 | } else if ("64".equals(dataModel)) { 27 | bits = "64"; 28 | } else { 29 | bits = (arch.contains("64") || arch.equalsIgnoreCase("sparcv9")) ? "64" : "32"; 30 | } 31 | 32 | return bits; 33 | } 34 | } 35 | 36 | private static boolean isArm() { 37 | return System.getProperty("os.arch").equals("arm"); 38 | } 39 | 40 | private static String getFloat() { 41 | if (isArm()) { 42 | return new File("/lib/arm-linux-gnueabihf").isDirectory() ? "hf" : "el"; 43 | } 44 | return ""; 45 | } 46 | 47 | public static final void init() { 48 | String arch = getArch(); 49 | try { 50 | NativeUtils.loadLibraryFromJar("/META-INF/native/linux-" + arch, new String[] { "video", "v4l4j" }); 51 | } catch (IOException e) { 52 | e.printStackTrace(); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/V4L4JDataBuffer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Gilles Gigan (gilles.gigan@gmail.com) 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by the 6 | * Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 11 | * or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | package au.edu.jcu.v4l4j; 19 | 20 | import java.awt.image.DataBuffer; 21 | 22 | /** 23 | * This class represents a {@link DataBuffer} containing an image 24 | * obtained though v4l4j. 25 | * @author gilles 26 | * 27 | */ 28 | class V4L4JDataBuffer extends DataBuffer { 29 | private byte byteArray[]; 30 | 31 | V4L4JDataBuffer(byte array[]) { 32 | super(TYPE_BYTE, array.length); 33 | byteArray = array; 34 | } 35 | 36 | public void setNewFrameSize(int s){ 37 | size = s; 38 | } 39 | 40 | @Override 41 | public int getElem(int bank, int i) { 42 | if (bank != 0) 43 | throw new IndexOutOfBoundsException("Only one bank in this data buffer"); 44 | 45 | return (int)(byteArray[i]) & 0xff; 46 | } 47 | 48 | @Override 49 | public void setElem(int bank, int i, int val) { 50 | // Do nothing 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/V4L4JRaster.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Gilles Gigan (gilles.gigan@gmail.com) 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by the 6 | * Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 11 | * or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | package au.edu.jcu.v4l4j; 19 | 20 | import java.awt.Point; 21 | import java.awt.image.DataBuffer; 22 | import java.awt.image.DataBufferByte; 23 | import java.awt.image.Raster; 24 | import java.awt.image.SampleModel; 25 | import java.awt.image.WritableRaster; 26 | 27 | /** 28 | * We need our own implementation of a WritableRaster because we cannot create one 29 | * with {@link Raster#createInterleavedRaster(DataBuffer, int, int, int, int, int[], Point)} as 30 | * we cannot pass a {@link V4L4JDataBuffer} to it, it will throw an exception because 31 | * it expects a {@link DataBufferByte} object. 32 | * @author gilles 33 | * 34 | */ 35 | public class V4L4JRaster extends WritableRaster { 36 | 37 | public V4L4JRaster(SampleModel sampleModel, DataBuffer dataBuffer, 38 | Point origin) { 39 | super(sampleModel, dataBuffer, origin); 40 | // TODO Auto-generated constructor stub 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/exceptions/V4L4JException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2008 Gilles Gigan (gilles.gigan@gmail.com) 3 | * eResearch Centre, James Cook University (eresearch.jcu.edu.au) 4 | * 5 | * This program was developed as part of the ARCHER project 6 | * (Australian Research Enabling Environment) funded by a 7 | * Systemic Infrastructure Initiative (SII) grant and supported by the Australian 8 | * Department of Innovation, Industry, Science and Research 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17 | * or FITNESS FOR A PARTICULAR PURPOSE. 18 | * See the GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | * 23 | */ 24 | 25 | package au.edu.jcu.v4l4j.exceptions; 26 | 27 | /** 28 | * A V4L4JExcption is the common superclass of all exceptions thrown by v4l4j. 29 | * @author gilles 30 | */ 31 | public class V4L4JException extends Exception { 32 | 33 | private static final long serialVersionUID = -8247407640809375121L; 34 | public V4L4JException(String message) { 35 | super(message); 36 | } 37 | public V4L4JException(String message, Throwable throwable) { 38 | super(message, throwable); 39 | } 40 | public V4L4JException(Throwable throwable) { 41 | super(throwable); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/exceptions/InvalidValue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2008 Gilles Gigan (gilles.gigan@gmail.com) 3 | * eResearch Centre, James Cook University (eresearch.jcu.edu.au) 4 | * 5 | * This program was developed as part of the ARCHER project 6 | * (Australian Research Enabling Environment) funded by a 7 | * Systemic Infrastructure Initiative (SII) grant and supported by the Australian 8 | * Department of Innovation, Industry, Science and Research 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17 | * or FITNESS FOR A PARTICULAR PURPOSE. 18 | * See the GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | * 23 | */ 24 | package au.edu.jcu.v4l4j.exceptions; 25 | 26 | /** 27 | * Exceptions of this type are thrown when trying ti set an incorrect value on a control. 28 | * @author gilles 29 | * 30 | */ 31 | public class InvalidValue extends RuntimeException { 32 | private static final long serialVersionUID = -3506474708008499397L; 33 | 34 | public InvalidValue(String message) { 35 | super(message); 36 | } 37 | 38 | public InvalidValue(String message, Throwable throwable) { 39 | super(message, throwable); 40 | } 41 | 42 | public InvalidValue(Throwable throwable) { 43 | super(throwable); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/exceptions/UnsupportedMethod.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2008 Gilles Gigan (gilles.gigan@gmail.com) 3 | * eResearch Centre, James Cook University (eresearch.jcu.edu.au) 4 | * 5 | * This program was developed as part of the ARCHER project 6 | * (Australian Research Enabling Environment) funded by a 7 | * Systemic Infrastructure Initiative (SII) grant and supported by the Australian 8 | * Department of Innovation, Industry, Science and Research 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17 | * or FITNESS FOR A PARTICULAR PURPOSE. 18 | * See the GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | * 23 | */ 24 | package au.edu.jcu.v4l4j.exceptions; 25 | 26 | /** 27 | * Exceptions of this type are thrown when calling an incorrect method on a 28 | * control or video frame 29 | * @author gilles 30 | * 31 | */ 32 | public class UnsupportedMethod extends RuntimeException { 33 | private static final long serialVersionUID = -8801339441741012577L; 34 | 35 | public UnsupportedMethod(String message) { 36 | super(message); 37 | } 38 | 39 | public UnsupportedMethod(String message, Throwable throwable) { 40 | super(message, throwable); 41 | } 42 | 43 | public UnsupportedMethod(Throwable throwable) { 44 | super(throwable); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/exceptions/ControlException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2008 Gilles Gigan (gilles.gigan@gmail.com) 3 | * eResearch Centre, James Cook University (eresearch.jcu.edu.au) 4 | * 5 | * This program was developed as part of the ARCHER project 6 | * (Australian Research Enabling Environment) funded by a 7 | * Systemic Infrastructure Initiative (SII) grant and supported by the Australian 8 | * Department of Innovation, Industry, Science and Research 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17 | * or FITNESS FOR A PARTICULAR PURPOSE. 18 | * See the GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | * 23 | */ 24 | package au.edu.jcu.v4l4j.exceptions; 25 | /** 26 | * Exceptions of this type are thrown whenever an error occurs retrieving or setting 27 | * the value of a control 28 | * @author gilles 29 | * 30 | */ 31 | public class ControlException extends V4L4JException{ 32 | 33 | private static final long serialVersionUID = -8310718978974706151L; 34 | 35 | public ControlException(String message) { 36 | super(message); 37 | } 38 | 39 | public ControlException(String message, Throwable throwable) { 40 | super(message, throwable); 41 | } 42 | 43 | public ControlException(Throwable throwable) { 44 | super(throwable); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/exceptions/CaptureChannelException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2008 Gilles Gigan (gilles.gigan@gmail.com) 3 | * eResearch Centre, James Cook University (eresearch.jcu.edu.au) 4 | * 5 | * This program was developed as part of the ARCHER project 6 | * (Australian Research Enabling Environment) funded by a 7 | * Systemic Infrastructure Initiative (SII) grant and supported by the Australian 8 | * Department of Innovation, Industry, Science and Research 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17 | * or FITNESS FOR A PARTICULAR PURPOSE. 18 | * See the GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | * 23 | */ 24 | 25 | package au.edu.jcu.v4l4j.exceptions; 26 | 27 | /** 28 | * This class of exception is thrown when the specified capture channel is invalid. 29 | * @author gilles 30 | */ 31 | public class CaptureChannelException extends V4L4JException { 32 | 33 | private static final long serialVersionUID = -3338859321078232443L; 34 | 35 | public CaptureChannelException(String message) { 36 | super(message); 37 | } 38 | 39 | public CaptureChannelException(String message, Throwable throwable) { 40 | super(message, throwable); 41 | } 42 | 43 | public CaptureChannelException(Throwable throwable) { 44 | super(throwable); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/exceptions/JNIException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2008 Gilles Gigan (gilles.gigan@gmail.com) 3 | * eResearch Centre, James Cook University (eresearch.jcu.edu.au) 4 | * 5 | * This program was developed as part of the ARCHER project 6 | * (Australian Research Enabling Environment) funded by a 7 | * Systemic Infrastructure Initiative (SII) grant and supported by the Australian 8 | * Department of Innovation, Industry, Science and Research 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17 | * or FITNESS FOR A PARTICULAR PURPOSE. 18 | * See the GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | * 23 | */ 24 | package au.edu.jcu.v4l4j.exceptions; 25 | 26 | /** 27 | * Exceptions of this type are thrown when an JNI-related error occurs 28 | * (unable to find a class, unable to instantiate an object, ...) 29 | * @author gilles 30 | * 31 | */ 32 | public class JNIException extends RuntimeException { 33 | 34 | private static final long serialVersionUID = -389938018936315368L; 35 | 36 | public JNIException(String message) { 37 | super(message); 38 | } 39 | 40 | public JNIException(String message, Throwable throwable) { 41 | super(message, throwable); 42 | } 43 | 44 | public JNIException(Throwable throwable) { 45 | super(throwable); 46 | } 47 | } -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/exceptions/VideoStandardException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2008 Gilles Gigan (gilles.gigan@gmail.com) 3 | * eResearch Centre, James Cook University (eresearch.jcu.edu.au) 4 | * 5 | * This program was developed as part of the ARCHER project 6 | * (Australian Research Enabling Environment) funded by a 7 | * Systemic Infrastructure Initiative (SII) grant and supported by the Australian 8 | * Department of Innovation, Industry, Science and Research 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17 | * or FITNESS FOR A PARTICULAR PURPOSE. 18 | * See the GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | * 23 | */ 24 | 25 | package au.edu.jcu.v4l4j.exceptions; 26 | 27 | /** 28 | * This class of exception is thrown when the requested video standard is invalid/not supported. 29 | * @author gilles 30 | */ 31 | public class VideoStandardException extends V4L4JException { 32 | 33 | private static final long serialVersionUID = -3338859321078232443L; 34 | 35 | public VideoStandardException(String message) { 36 | super(message); 37 | } 38 | 39 | public VideoStandardException(String message, Throwable throwable) { 40 | super(message, throwable); 41 | } 42 | 43 | public VideoStandardException(Throwable throwable) { 44 | super(throwable); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/exceptions/ImageDimensionsException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2008 Gilles Gigan (gilles.gigan@gmail.com) 3 | * eResearch Centre, James Cook University (eresearch.jcu.edu.au) 4 | * 5 | * This program was developed as part of the ARCHER project 6 | * (Australian Research Enabling Environment) funded by a 7 | * Systemic Infrastructure Initiative (SII) grant and supported by the Australian 8 | * Department of Innovation, Industry, Science and Research 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17 | * or FITNESS FOR A PARTICULAR PURPOSE. 18 | * See the GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | * 23 | */ 24 | 25 | package au.edu.jcu.v4l4j.exceptions; 26 | 27 | /** 28 | * This class of exception is thrown when the specified capture width / height is invalid / not supported. 29 | * @author gilles 30 | */ 31 | public class ImageDimensionsException extends V4L4JException { 32 | 33 | private static final long serialVersionUID = -3338859321078232443L; 34 | 35 | public ImageDimensionsException(String message) { 36 | super(message); 37 | } 38 | 39 | public ImageDimensionsException(String message, Throwable throwable) { 40 | super(message, throwable); 41 | } 42 | 43 | public ImageDimensionsException(Throwable throwable) { 44 | super(throwable); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/exceptions/NoTunerException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2008 Gilles Gigan (gilles.gigan@gmail.com) 3 | * eResearch Centre, James Cook University (eresearch.jcu.edu.au) 4 | * 5 | * This program was developed as part of the ARCHER project 6 | * (Australian Research Enabling Environment) funded by a 7 | * Systemic Infrastructure Initiative (SII) grant and supported by the Australian 8 | * Department of Innovation, Industry, Science and Research 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17 | * or FITNESS FOR A PARTICULAR PURPOSE. 18 | * See the GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | * 23 | */ 24 | package au.edu.jcu.v4l4j.exceptions; 25 | 26 | /** 27 | * This class of exception is thrown when the Input.getTuner() method is invoked on 28 | * an input with no tuner (Input.getType() returns Input.CAMERA). 29 | * @author gilles 30 | */ 31 | public class NoTunerException extends V4L4JException { 32 | 33 | private static final long serialVersionUID = -4596596557974047977L; 34 | 35 | public NoTunerException(String message) { 36 | super(message); 37 | } 38 | 39 | public NoTunerException(String message, Throwable throwable) { 40 | super(message, throwable); 41 | } 42 | 43 | public NoTunerException(Throwable throwable) { 44 | super(throwable); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/exceptions/ImageFormatException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2008 Gilles Gigan (gilles.gigan@gmail.com) 3 | * eResearch Centre, James Cook University (eresearch.jcu.edu.au) 4 | * 5 | * This program was developed as part of the ARCHER project 6 | * (Australian Research Enabling Environment) funded by a 7 | * Systemic Infrastructure Initiative (SII) grant and supported by the Australian 8 | * Department of Innovation, Industry, Science and Research 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17 | * or FITNESS FOR A PARTICULAR PURPOSE. 18 | * See the GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | * 23 | */ 24 | 25 | package au.edu.jcu.v4l4j.exceptions; 26 | 27 | /** 28 | * This class of exception is thrown when v4l4j was unable to negotiate a suitable image format with the device. 29 | * See v4l4j README file for more information. 30 | * @author gilles 31 | */ 32 | public class ImageFormatException extends V4L4JException { 33 | 34 | private static final long serialVersionUID = -3338859321078232443L; 35 | 36 | public ImageFormatException(String message) { 37 | super(message); 38 | } 39 | 40 | public ImageFormatException(String message, Throwable throwable) { 41 | super(message, throwable); 42 | } 43 | 44 | public ImageFormatException(Throwable throwable) { 45 | super(throwable); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/exceptions/ReleaseException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2008 Gilles Gigan (gilles.gigan@gmail.com) 3 | * eResearch Centre, James Cook University (eresearch.jcu.edu.au) 4 | * 5 | * This program was developed as part of the ARCHER project 6 | * (Australian Research Enabling Environment) funded by a 7 | * Systemic Infrastructure Initiative (SII) grant and supported by the Australian 8 | * Department of Innovation, Industry, Science and Research 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17 | * or FITNESS FOR A PARTICULAR PURPOSE. 18 | * See the GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | * 23 | */ 24 | package au.edu.jcu.v4l4j.exceptions; 25 | 26 | import au.edu.jcu.v4l4j.VideoDevice; 27 | 28 | /** 29 | * This class of exception is thrown when trying to release a 30 | * {@link VideoDevice} using its {@link VideoDevice#release(boolean)} method 31 | * with a true argument, when the video device is still in use 32 | * @author gilles 33 | * 34 | */ 35 | public class ReleaseException extends RuntimeException { 36 | 37 | private static final long serialVersionUID = -7410432021368200123L; 38 | 39 | public ReleaseException(String message) { 40 | super(message); 41 | } 42 | 43 | public ReleaseException(String message, Throwable throwable) { 44 | super(message, throwable); 45 | } 46 | 47 | public ReleaseException(Throwable throwable) { 48 | super(throwable); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/exceptions/StateException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2008 Gilles Gigan (gilles.gigan@gmail.com) 3 | * eResearch Centre, James Cook University (eresearch.jcu.edu.au) 4 | * 5 | * This program was developed as part of the ARCHER project 6 | * (Australian Research Enabling Environment) funded by a 7 | * Systemic Infrastructure Initiative (SII) grant and supported by the Australian 8 | * Department of Innovation, Industry, Science and Research 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17 | * or FITNESS FOR A PARTICULAR PURPOSE. 18 | * See the GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | * 23 | */ 24 | 25 | package au.edu.jcu.v4l4j.exceptions; 26 | 27 | /** 28 | * This class of exception is thrown when a unexpected method is invoked 29 | * on a v4l4j object the framegrabber when its current state forbids the 30 | * execution of that method. For instance, calling 31 | * getVideoFrame() before calling init(), 32 | * startCapture() is illegal and getVideoFrame() 33 | * will throw a StateException. 34 | * @author gilles 35 | */ 36 | public class StateException extends RuntimeException { 37 | 38 | private static final long serialVersionUID = 1351714754008657462L; 39 | 40 | public StateException(String message) { 41 | super(message); 42 | } 43 | 44 | public StateException(String message, Throwable throwable) { 45 | super(message, throwable); 46 | } 47 | 48 | public StateException(Throwable throwable) { 49 | super(throwable); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/exceptions/InitialisationException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2008 Gilles Gigan (gilles.gigan@gmail.com) 3 | * eResearch Centre, James Cook University (eresearch.jcu.edu.au) 4 | * 5 | * This program was developed as part of the ARCHER project 6 | * (Australian Research Enabling Environment) funded by a 7 | * Systemic Infrastructure Initiative (SII) grant and supported by the Australian 8 | * Department of Innovation, Industry, Science and Research 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17 | * or FITNESS FOR A PARTICULAR PURPOSE. 18 | * See the GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | * 23 | */ 24 | 25 | package au.edu.jcu.v4l4j.exceptions; 26 | 27 | /** 28 | * This class of exception is thrown when the initialisation a Video4Linux device fails. 29 | * The initialisation is made of three steps: allocating memory, opening the device file 30 | * and checking the version of V4L. Opening the device fail could fail if the device is 31 | * already being used, or if the permissions forbid it. Checking the V4L version will fail 32 | * only if the device file belongs to a non-V4L device. If either of the three steps 33 | * fails, an InitialistationException is thrown. 34 | * @author gilles 35 | */ 36 | public class InitialisationException extends V4L4JException { 37 | 38 | private static final long serialVersionUID = -3338859321078232443L; 39 | 40 | public InitialisationException(String message) { 41 | super(message); 42 | } 43 | 44 | public InitialisationException(String message, Throwable throwable) { 45 | super(message, throwable); 46 | } 47 | 48 | public InitialisationException(Throwable throwable) { 49 | super(throwable); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/CaptureCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Gilles Gigan (gilles.gigan@gmail.com) 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by the 6 | * Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 11 | * or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | package au.edu.jcu.v4l4j; 19 | 20 | import au.edu.jcu.v4l4j.exceptions.V4L4JException; 21 | 22 | /** 23 | * Objects implementing this interface receive notifications from frame grabbers 24 | * when new captured frames become available, or an exception 25 | * occurs during a capture. In order to capture from a video device, 26 | * you must instantiate an object which implements this interface 27 | * and pass it to a frame grabber 28 | * (via @link {@link FrameGrabber#setCaptureCallback(CaptureCallback)}). 29 | * When you start the capture, v4l4j will call {@link #nextFrame(VideoFrame)} 30 | * to deliver new frames to your application as soon as they arrive. 31 | * Check the {@link FrameGrabber} page for more information. 32 | * @author gilles 33 | * 34 | */ 35 | public interface CaptureCallback { 36 | 37 | /** 38 | * During a capture, this method is called by v4l4j to provide 39 | * the latest video frame. It is important that you minimise 40 | * the amount of code and processing done in this method in 41 | * order to maintain the appropriate frame rate. 42 | *
Make sure the frame is recycled when no longer used. It does not 43 | * have to be done in this method, but it must be done at some point in 44 | * the near future. 45 | * @param frame the latest captured frame 46 | */ 47 | public void nextFrame(VideoFrame frame); 48 | 49 | /** 50 | * This method is called if an error occurs during capture. 51 | * It is safe to assume that if this method is called, 52 | * no more calls to {@link #nextFrame(VideoFrame)} will follow. 53 | * @param e the exception that was raised during the capture. 54 | */ 55 | public void exceptionReceived(V4L4JException e); 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/JPEGVideoFrame.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Gilles Gigan (gilles.gigan@gmail.com) 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by the 6 | * Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 11 | * or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | package au.edu.jcu.v4l4j; 19 | 20 | import java.awt.image.BufferedImage; 21 | import java.awt.image.Raster; 22 | import java.awt.image.WritableRaster; 23 | import java.io.ByteArrayInputStream; 24 | import java.io.IOException; 25 | 26 | import javax.imageio.ImageIO; 27 | 28 | import au.edu.jcu.v4l4j.exceptions.UnsupportedMethod; 29 | 30 | /** 31 | * Instances of this class encapsulate image data for a JPEG compressed 32 | * image. They will not generate a {@link Raster} as rasters only support 33 | * uncompressed format. They do support however creation of {@link BufferedImage}s. 34 | * @author gilles 35 | * 36 | */ 37 | class JPEGVideoFrame extends BaseVideoFrame { 38 | 39 | JPEGVideoFrame(AbstractGrabber grabber, int bufferSize) { 40 | super(grabber, bufferSize); 41 | } 42 | 43 | @Override 44 | protected WritableRaster refreshRaster() { 45 | throw new UnsupportedMethod("A raster cannot be generated for a JPEG frame"); 46 | } 47 | 48 | @Override 49 | protected BufferedImage refreshBufferedImage() { 50 | try { 51 | return ImageIO.read(new ByteArrayInputStream(frameBuffer, 0, frameLength)); 52 | } catch (IOException e) { 53 | System.err.println("It seems your JVM is unable to decode this image."); 54 | 55 | // print supported image types and mime types 56 | System.err.println("Supported image types:"); 57 | String supportedTypes[] = ImageIO.getReaderFormatNames(); 58 | for (String name : supportedTypes) 59 | System.err.println(name); 60 | System.err.println("Supported MIME types:"); 61 | String supportedMimeTypes[] = ImageIO.getReaderMIMETypes(); 62 | for (String name : supportedMimeTypes) 63 | System.err.println(name); 64 | 65 | e.printStackTrace(); 66 | throw new UnsupportedMethod("Unable to decode the image", e); 67 | } 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/UncompressedVideoFrame.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Gilles Gigan (gilles.gigan@gmail.com) 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by the 6 | * Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 11 | * or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | package au.edu.jcu.v4l4j; 19 | 20 | import java.awt.Point; 21 | import java.awt.Transparency; 22 | import java.awt.color.ColorSpace; 23 | import java.awt.image.BufferedImage; 24 | import java.awt.image.ComponentColorModel; 25 | import java.awt.image.DataBuffer; 26 | import java.awt.image.Raster; 27 | import java.awt.image.SampleModel; 28 | 29 | /** 30 | * This class of object encapsulate data for a video frame in an uncompressed image format. 31 | * Image using a format that can be stored in a {@link Raster} must pass a {@link SampleModel} to 32 | * the constructor. Image using a format that can be encapsulated in a {@link BufferedImage} 33 | * must pass a {@link ColorSpace} to the constructor. 34 | * @author gilles 35 | * 36 | */ 37 | class UncompressedVideoFrame extends BaseVideoFrame { 38 | 39 | /** 40 | * This method builds a video frame object. 41 | * @param grabber the {@link FrameGrabber} to which this frame must be returned to when recycled 42 | * @param bufferSize the size in bytes of the byte array to be created 43 | * @param sm the SampleModel used to build a WritableRaster or null if 44 | * no raster should be created. 45 | * @param cs the ColorSpace used to create a BuffereddImage, or null if no 46 | * BufferedImage should be created 47 | */ 48 | UncompressedVideoFrame(AbstractGrabber grabber, int bufferSize, 49 | SampleModel sm, ColorSpace cs) { 50 | super(grabber, bufferSize); 51 | 52 | // create raster if a sample model was given 53 | if (sm != null) { 54 | raster = new V4L4JRaster(sm, dataBuffer, new Point(0,0)); 55 | 56 | // create buffered image if a colorspace was given 57 | if (cs != null) 58 | bufferedImage = new BufferedImage( 59 | new ComponentColorModel(cs, 60 | false, 61 | false, 62 | Transparency.OPAQUE, 63 | DataBuffer.TYPE_BYTE), 64 | raster,false,null 65 | ); 66 | else 67 | bufferedImage = null; 68 | 69 | } else 70 | raster = null; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/TunerList.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2008 Gilles Gigan (gilles.gigan@gmail.com) 3 | * eResearch Centre, James Cook University (eresearch.jcu.edu.au) 4 | * 5 | * This program was developed as part of the ARCHER project 6 | * (Australian Research Enabling Environment) funded by a 7 | * Systemic Infrastructure Initiative (SII) grant and supported by the Australian 8 | * Department of Innovation, Industry, Science and Research 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17 | * or FITNESS FOR A PARTICULAR PURPOSE. 18 | * See the GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | * 23 | */ 24 | package au.edu.jcu.v4l4j; 25 | 26 | import java.util.List; 27 | import java.util.Vector; 28 | 29 | import au.edu.jcu.v4l4j.exceptions.StateException; 30 | 31 | /** 32 | * Objects of this class encapsulate a list of available {@link Tuner}s. 33 | * This class can not be directly instantiated. Instead, to retrieve a list of 34 | * tuners from a {@link VideoDevice}, use its 35 | * {@link VideoDevice#getTunerList() getTunerList()} method. 36 | * @author gilles 37 | * 38 | */ 39 | public class TunerList { 40 | private Vector tuners; 41 | private boolean released; 42 | 43 | /** 44 | * This constructor builds a control list from the given list. (a copy of 45 | * the list object is made). 46 | * @param c the tuner list used to initialise this object. 47 | */ 48 | TunerList(List t){ 49 | tuners= new Vector(t); 50 | released = false; 51 | } 52 | 53 | /** 54 | * This method returns a copy of the tuner list. 55 | * @return a copy of the tuner list. 56 | * @throws StateException if this tuner list has been released and must 57 | * not be used anymore 58 | */ 59 | public synchronized List getList(){ 60 | checkReleased(); 61 | return new Vector(tuners); 62 | } 63 | 64 | /** 65 | * This method returns a tuner given its index. 66 | * @return the tuner matching the given index, null otherwise 67 | * @throws StateException if this tuner list has been released and must not 68 | * be used anymore 69 | * @throws ArrayIndexOutOfBoundsException if the given index is out of bounds 70 | */ 71 | public synchronized Tuner getTuner(int i){ 72 | checkReleased(); 73 | for(Tuner t: tuners) 74 | if(t.getIndex()==i) 75 | return t; 76 | 77 | throw new ArrayIndexOutOfBoundsException("No tuner with such index"); 78 | } 79 | 80 | /** 81 | * This method released the tuner list, and all tuners in it. 82 | */ 83 | synchronized void release(){ 84 | released = true; 85 | for(Tuner t: tuners) 86 | t.release(); 87 | } 88 | 89 | private void checkReleased(){ 90 | if(released) 91 | throw new StateException("The tuner list has been released and " + 92 | "must not be used"); 93 | } 94 | } 95 | 96 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/TunerInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2008 Gilles Gigan (gilles.gigan@gmail.com) 3 | * eResearch Centre, James Cook University (eresearch.jcu.edu.au) 4 | * 5 | * This program was developed as part of the ARCHER project 6 | * (Australian Research Enabling Environment) funded by a 7 | * Systemic Infrastructure Initiative (SII) grant and supported by the Australian 8 | * Department of Innovation, Industry, Science and Research 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17 | * or FITNESS FOR A PARTICULAR PURPOSE. 18 | * See the GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | * 23 | */ 24 | package au.edu.jcu.v4l4j; 25 | 26 | /** 27 | * Object of this class encapsulate information about a tuner: 28 | *
    29 | *
  • its type: {@link V4L4JConstants#TUNER_TYPE_RADIO} or {@link V4L4JConstants#TUNER_TYPE_TV},
  • 30 | *
  • the frequency unit: {@link V4L4JConstants#FREQ_KHZ} or {@link V4L4JConstants#FREQ_MHZ},
  • 31 | *
  • the name of the tuner,
  • 32 | *
  • the index of the tuner,
  • 33 | *
  • and the lowest and highest tunable frequencies.
  • 34 | *
35 | * @author gilles 36 | * 37 | */ 38 | public class TunerInfo { 39 | /** 40 | * The type of this tuner (RADIO or TV) 41 | */ 42 | private int type; 43 | 44 | /** 45 | * Frequency unit (MHZ or KHZ) 46 | */ 47 | private int unit; 48 | 49 | /** 50 | * The lowest & highest tunable frequencies 51 | */ 52 | private long rangeLow, rangeHigh; 53 | 54 | /** 55 | * The name of this tuner 56 | */ 57 | private String name; 58 | 59 | /** 60 | * The V4L index of this tuner 61 | */ 62 | private int index; 63 | 64 | 65 | TunerInfo(String n, int id, int u, int t, long low, long high){ 66 | type = t; 67 | unit = u; 68 | rangeLow = low & 0xffffffff; 69 | rangeHigh = high & 0xffffffff; 70 | name = n; 71 | index = id; 72 | 73 | } 74 | 75 | /** 76 | * This method returns the type of this tuner ({@link V4L4JConstants#TUNER_TYPE_RADIO} 77 | * or {@link V4L4JConstants#TUNER_TYPE_TV}). 78 | * @return the type 79 | */ 80 | public int getType() { 81 | return type; 82 | } 83 | 84 | /** 85 | * This method returns the unit used by this tuner ({@link V4L4JConstants#FREQ_MHZ} 86 | * or {@link V4L4JConstants#FREQ_KHZ}). 87 | * @return the unit ({@link V4L4JConstants#FREQ_MHZ} 88 | * or {@link V4L4JConstants#FREQ_KHZ}). 89 | */ 90 | public int getUnit() { 91 | return unit; 92 | } 93 | 94 | 95 | /** 96 | * This method returns the lowest tunable frequency supported by this tuner. 97 | * @return the lowest tunable frequency supported by this tuner. 98 | */ 99 | public double getRangeLow() { 100 | return rangeLow*0.0625; 101 | } 102 | 103 | 104 | /** 105 | * This method returns the highest tunable frequency supported by this tuner. 106 | * @return the highest tunable frequency supported by this tuner. 107 | */ 108 | public double getRangeHigh() { 109 | return rangeHigh*0.0625; 110 | } 111 | 112 | 113 | /** 114 | * This method returns the name of this tuner. 115 | * @return the name of this tuner. 116 | */ 117 | public String getName() { 118 | return name; 119 | } 120 | 121 | /** 122 | * This method returns the V4L index of this tuner. 123 | * @return the V4L index of this tuner. 124 | */ 125 | public int getIndex(){ 126 | return index; 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/RawFrameGrabber.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2008 Gilles Gigan (gilles.gigan@gmail.com) 3 | * eResearch Centre, James Cook University (eresearch.jcu.edu.au) 4 | * 5 | * This program was developed as part of the ARCHER project 6 | * (Australian Research Enabling Environment) funded by a 7 | * Systemic Infrastructure Initiative (SII) grant and supported by the Australian 8 | * Department of Innovation, Industry, Science and Research 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17 | * or FITNESS FOR A PARTICULAR PURPOSE. 18 | * See the GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | * 23 | */ 24 | 25 | package au.edu.jcu.v4l4j; 26 | 27 | import java.util.concurrent.ThreadFactory; 28 | 29 | import au.edu.jcu.v4l4j.exceptions.ImageFormatException; 30 | import au.edu.jcu.v4l4j.exceptions.StateException; 31 | 32 | /** 33 | * This class provides methods to capture raw frames from a {@link VideoDevice}. 34 | * Raw means that the image format will be left untouched and passed on straight 35 | * away to the caller. v4l4j also provides additional frame grabber classes 36 | * which encodes frames in a specific format before handing them out. 37 | * FrameGrabber objects are not instantiated directly. Instead, the 38 | * {@link VideoDevice#getRawFrameGrabber(int, int, int, int) getRawFrameGrabber()} 39 | * method must be called on the associated {@link VideoDevice}. Raw frame grabbers 40 | * implement the {@link FrameGrabber} interface which provides methods to handle 41 | * video capture. See {@link FrameGrabber its documentation} for more information. 42 | * 43 | * @see FrameGrabber {@link FrameGrabber} 44 | * @see JPEGFrameGrabber {@link RGBFrameGrabber} 45 | * @author gilles 46 | * 47 | */ 48 | public class RawFrameGrabber extends AbstractGrabber { 49 | /** 50 | * This constructor builds a raw FrameGrabber object used to raw frames 51 | * from a video source. 52 | * @param di the DeviceInfo of the VideoDevice who created this frame grabber 53 | * @param o a JNI pointer to the v4l4j_device structure 54 | * @param w the requested frame width 55 | * @param h the requested frame height 56 | * @param ch the input index, as returned by 57 | * InputInfo.getIndex() 58 | * @param std the video standard, as returned by 59 | * InputInfo.getSupportedStandards() (see V4L4JConstants) 60 | * @param t the {@link Tuner} associated with this frame grabber or 61 | * null. 62 | * @param imf the image format frames should be captured in 63 | * @param factory the thread factory to sue when creating the push source 64 | * @throws ImageFormatException if the image format is null and a RAW frame 65 | * grabber is to be created 66 | */ 67 | RawFrameGrabber(DeviceInfo di, long o, int w, int h, int ch, 68 | int std, Tuner t, ImageFormat imf, ThreadFactory factory) throws ImageFormatException{ 69 | super(di, o,w,h,ch,std,t,imf, RAW_GRABBER, factory); 70 | } 71 | 72 | /** 73 | * This method returns the native image format used by this 74 | * FrameGrabber. The returned format specifies the image format in 75 | * which frames captured by this grabber are. 76 | * @return the native image format used by this FrameGrabber. 77 | * @throws StateException if this 78 | * FrameGrabber has been already released, and therefore must 79 | * not be used anymore. 80 | */ 81 | public ImageFormat getImageFormat(){ 82 | state.checkReleased(); 83 | return dInfo.getFormatList().getNativeFormat(format); 84 | } 85 | 86 | @Override 87 | protected void createBuffers(int bufferSize) { 88 | int numberOfBuffers = nbV4LBuffers; 89 | 90 | while(numberOfBuffers-- > 0) 91 | videoFrames.add( new UncompressedVideoFrame(this, bufferSize, null,null) ); 92 | } 93 | } 94 | 95 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/ControlList.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2008 Gilles Gigan (gilles.gigan@gmail.com) 3 | * eResearch Centre, James Cook University (eresearch.jcu.edu.au) 4 | * 5 | * This program was developed as part of the ARCHER project 6 | * (Australian Research Enabling Environment) funded by a 7 | * Systemic Infrastructure Initiative (SII) grant and supported by the Australian 8 | * Department of Innovation, Industry, Science and Research 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17 | * or FITNESS FOR A PARTICULAR PURPOSE. 18 | * See the GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | * 23 | */ 24 | package au.edu.jcu.v4l4j; 25 | 26 | import java.util.Hashtable; 27 | import java.util.List; 28 | import java.util.Vector; 29 | 30 | import au.edu.jcu.v4l4j.exceptions.StateException; 31 | 32 | /** 33 | * Objects of this class encapsulate a list of video source {@link Control}. This class 34 | * can not be directly instantiated. Instead, to retrieve a list of controls 35 | * from a {@link VideoDevice}, use its 36 | * {@link VideoDevice#getControlList() getControlList()} method. Once 37 | * the control list and associated controls are no longer needed, they must be 38 | * released by calling {@link VideoDevice#releaseControlList() releaseControlList()}. 39 | * After that, neither the list nor the controls themselves must be used. If 40 | * any attempt to use them is made, a {@link StateException} will be raised. 41 | * @author gilles 42 | * 43 | */ 44 | public class ControlList { 45 | private Hashtable controls; 46 | private boolean released; 47 | 48 | /** 49 | * This constructor builds a control list from the given list. (no copy is made) 50 | * @param c the control list used to initialise this object. 51 | */ 52 | ControlList(Hashtable c){ 53 | controls = c; 54 | released = false; 55 | } 56 | 57 | /** 58 | * This constructor builds a control list from the given list. (no copy is made) 59 | * @param c the control list used to initialise this object. 60 | */ 61 | ControlList(Control[] c){ 62 | controls = new Hashtable(); 63 | for(Control ctrl: c) 64 | controls.put(ctrl.getName(), ctrl); 65 | 66 | released = false; 67 | } 68 | 69 | /** 70 | * This method returns a map of control names and controls 71 | * @return a map of control names and controls 72 | * @throws StateException if this control list has been released and must not be used anymore 73 | */ 74 | public synchronized Hashtable getTable(){ 75 | checkReleased(); 76 | return new Hashtable(controls); 77 | } 78 | 79 | /** 80 | * This method returns a list of {@link Control}s 81 | * @return a list of {@link Control}s 82 | * @throws StateException if this control list has been released and must not be used anymore 83 | */ 84 | public synchronized List getList(){ 85 | checkReleased(); 86 | return new Vector(controls.values()); 87 | } 88 | 89 | /** 90 | * This method returns a control given its name. 91 | * @return the control matching the given name, null otherwise 92 | * @throws StateException if this control list has been released and must not be used anymore 93 | */ 94 | public synchronized Control getControl(String n){ 95 | checkReleased(); 96 | return controls.get(n); 97 | } 98 | 99 | /** 100 | * This method released the control list, and all controls in it. 101 | */ 102 | synchronized void release(){ 103 | released = true; 104 | for(Control c: controls.values()) 105 | c.release(); 106 | } 107 | 108 | private void checkReleased(){ 109 | if(released) 110 | throw new StateException("The control list has been released and must not be used"); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | org.sonatype.oss 7 | oss-parent 8 | 7 9 | 10 | 11 | com.github.sarxos 12 | v4l4j 13 | 0.9.1-r507 14 | 15 | V4L4J 16 | https://github.com/sarxos/v4l4j 17 | 18 | This is mavenized and customized fork of V4L4J by Gilles Gigan. It contains only 19 | Java source code (no natives) and *.so objects precompiled for several architectures. 20 | 21 | 22 | 2013 23 | 24 | 25 | UTF-8 26 | 27 | 28 | 29 | Bartosz Firyn (sarxos) 30 | https://github.com/sarxos 31 | 32 | 33 | 34 | 35 | GNU GPL v3 36 | https://github.com/sarxos/v4l4j/blob/master/COPYING 37 | repo,manual 38 | 39 | 40 | 41 | 42 | scm:git:git@github.com:sarxos/v4l4j.git 43 | scm:git:git@github.com:sarxos/v4l4j.git 44 | git@github.com:sarxos/v4l4j.git 45 | 46 | 47 | 48 | Google Groups 49 | https://groups.google.com/forum/#!forum/v4l4j 50 | 51 | 52 | 53 | 54 | doclint-java8-disable 55 | 56 | [1.8,) 57 | 58 | 59 | 60 | 61 | org.apache.maven.plugins 62 | maven-javadoc-plugin 63 | 64 | -Xdoclint:none 65 | 66 | 67 | 68 | 69 | 70 | 71 | release 72 | 73 | 74 | performRelease 75 | true 76 | 77 | 78 | 79 | 80 | 81 | org.apache.maven.plugins 82 | maven-source-plugin 83 | 2.1.2 84 | 85 | 86 | attach-sources 87 | 88 | jar 89 | 90 | 91 | 92 | 93 | 94 | org.apache.maven.plugins 95 | maven-javadoc-plugin 96 | 2.8.1 97 | 98 | 99 | attach-javadocs 100 | 101 | jar 102 | 103 | 104 | 105 | 106 | 107 | org.apache.maven.plugins 108 | maven-gpg-plugin 109 | 1.1 110 | 111 | 112 | sign-artifacts 113 | verify 114 | 115 | sign 116 | 117 | 118 | 119 | 120 | 121 | org.apache.maven.plugins 122 | maven-release-plugin 123 | 2.2.2 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | org.apache.maven.plugins 134 | maven-compiler-plugin 135 | 2.5.1 136 | 137 | 1.6 138 | 1.6 139 | 140 | 141 | 142 | 143 | 144 | org.apache.maven.wagon 145 | wagon-ftp 146 | 1.0-beta-7 147 | 148 | 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /src/main/java/com/github/sarxos/v4l4j/NativeUtils.java: -------------------------------------------------------------------------------- 1 | package com.github.sarxos.v4l4j; 2 | 3 | import java.io.*; 4 | import java.nio.file.FileSystemNotFoundException; 5 | import java.nio.file.FileSystems; 6 | import java.nio.file.Files; 7 | import java.nio.file.ProviderNotFoundException; 8 | import java.nio.file.StandardCopyOption; 9 | 10 | /** 11 | * A simple library class which helps with loading dynamic libraries stored in the 12 | * JAR archive. These libraries usually contain implementation of some methods in 13 | * native code (using JNI - Java Native Interface). 14 | * 15 | * @see http://adamheinrich.com/blog/2012/how-to-load-native-jni-library-from-jar 16 | * @see https://github.com/adamheinrich/native-utils 17 | * 18 | */ 19 | public class NativeUtils { 20 | 21 | /** 22 | * The minimum length a prefix for a file has to have according to {@link File#createTempFile(String, String)}}. 23 | */ 24 | private static final int MIN_PREFIX_LENGTH = 3; 25 | public static final String NATIVE_FOLDER_PATH_PREFIX = "nativeutils"; 26 | 27 | /** 28 | * Temporary directory which will contain the DLLs. 29 | */ 30 | private static File temporaryDir; 31 | 32 | /** 33 | * Private constructor - this class will never be instanced 34 | */ 35 | private NativeUtils() { 36 | } 37 | 38 | /** 39 | * Loads library from current JAR archive 40 | * 41 | * The file from JAR is copied into system temporary directory and then loaded. The temporary file is deleted after 42 | * exiting. 43 | * Method uses String as filename because the pathname is "abstract", not system-dependent. 44 | * 45 | * @param path The path of file inside JAR as absolute path (beginning with '/'), e.g. /package/File.ext 46 | * @throws IOException If temporary file creation or read/write operation fails 47 | * @throws IllegalArgumentException If source file (param path) does not exist 48 | * @throws IllegalArgumentException If the path is not absolute or if the filename is shorter than three characters 49 | * (restriction of {@link File#createTempFile(java.lang.String, java.lang.String)}). 50 | * @throws FileNotFoundException If the file could not be found inside the JAR. 51 | */ 52 | public static void loadLibraryFromJar(String path) throws IOException { 53 | 54 | if (null == path || !path.startsWith("/")) { 55 | throw new IllegalArgumentException("The path has to be absolute (start with '/')."); 56 | } 57 | 58 | // Obtain filename from path 59 | String[] parts = path.split("/"); 60 | String filename = (parts.length > 1) ? parts[parts.length - 1] : null; 61 | 62 | // Check if the filename is okay 63 | if (filename == null || filename.length() < MIN_PREFIX_LENGTH) { 64 | throw new IllegalArgumentException("The filename has to be at least 3 characters long."); 65 | } 66 | 67 | // Prepare temporary file 68 | if (temporaryDir == null) { 69 | temporaryDir = createTempDirectory(NATIVE_FOLDER_PATH_PREFIX); 70 | temporaryDir.deleteOnExit(); 71 | } 72 | 73 | File temp = new File(temporaryDir, filename); 74 | 75 | try (InputStream is = NativeUtils.class.getResourceAsStream(path)) { 76 | Files.copy(is, temp.toPath(), StandardCopyOption.REPLACE_EXISTING); 77 | } catch (IOException e) { 78 | temp.delete(); 79 | throw e; 80 | } catch (NullPointerException e) { 81 | temp.delete(); 82 | throw new FileNotFoundException("File " + path + " was not found inside JAR."); 83 | } 84 | 85 | try { 86 | System.load(temp.getAbsolutePath()); 87 | } finally { 88 | if (isPosixCompliant()) { 89 | // Assume POSIX compliant file system, can be deleted after loading 90 | temp.delete(); 91 | } else { 92 | // Assume non-POSIX, and don't delete until last file descriptor closed 93 | temp.deleteOnExit(); 94 | } 95 | } 96 | } 97 | 98 | private static boolean isPosixCompliant() { 99 | try { 100 | return FileSystems.getDefault() 101 | .supportedFileAttributeViews() 102 | .contains("posix"); 103 | } catch (FileSystemNotFoundException 104 | | ProviderNotFoundException 105 | | SecurityException e) { 106 | return false; 107 | } 108 | } 109 | 110 | private static File createTempDirectory(String prefix) throws IOException { 111 | String tempDir = System.getProperty("java.io.tmpdir"); 112 | File generatedDir = new File(tempDir, prefix + System.nanoTime()); 113 | 114 | if (!generatedDir.mkdir()) 115 | throw new IOException("Failed to create temp directory " + generatedDir.getName()); 116 | 117 | return generatedDir; 118 | } 119 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/ImageFormat.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2008 Gilles Gigan (gilles.gigan@gmail.com) 3 | * eResearch Centre, James Cook University (eresearch.jcu.edu.au) 4 | * 5 | * This program was developed as part of the ARCHER project 6 | * (Australian Research Enabling Environment) funded by a 7 | * Systemic Infrastructure Initiative (SII) grant and supported by the Australian 8 | * Department of Innovation, Industry, Science and Research 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17 | * or FITNESS FOR A PARTICULAR PURPOSE. 18 | * See the GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | * 23 | */ 24 | 25 | package au.edu.jcu.v4l4j; 26 | 27 | 28 | /** 29 | * Objects of this class represent an image format (YUV, RGB, GREY, BGR, ...) 30 | * and its supported capture resolutions and frame intervals. 31 | * ImageFormat objects have three members: a name, a unique index, 32 | * and a {@link ResolutionInfo} object which provides information on 33 | * supported capture resolutions and frame intervals for this format. 34 | * A list of known image format indexes can be found in 35 | * {@link V4L4JConstants}.IMF_*. 36 | * ImageFormats 37 | * are not directly instantiated. Instead, they can be enumerated by instantiating 38 | * a {@link VideoDevice}, and checking the {@link DeviceInfo} object associated 39 | * with it: 40 | *
41 | *
VideoDevice vd = new VideoDevice("/dev/video0"); 42 | *
vd.init(); 43 | *
List fmts = vd.getDeviceInfo().getFormatList().getNativeFormats(); 44 | *
for(ImageFormat im: fmts) 45 | *
   System.out.println("Format name: "+im); 46 | *
vd.release(); 47 | *

48 | * See the {@link ImageFormatList} documentation for more information. 49 | * 50 | * @see ImageFormatList 51 | * @author gilles 52 | * 53 | */ 54 | public class ImageFormat { 55 | 56 | /** 57 | * The name of this format 58 | */ 59 | private String name; 60 | 61 | /** 62 | * the libvideo Id for this format 63 | */ 64 | private int libvideoID; 65 | 66 | /** 67 | * Info on supported resolutions for this image format 68 | */ 69 | private ResolutionInfo resolutions; 70 | 71 | 72 | /** 73 | * This method builds a new Image format with the given name and index. It 74 | * also invokes a JNI method to retrieve the list of supported resolutions 75 | * Therefore, it MUST be called while the device info interface of libvideo 76 | * is checked out 77 | * @param n the name of this image format 78 | * @param i the index of this image format 79 | * @param o a C pointer to a struct v4l4j_device 80 | */ 81 | ImageFormat(String n, int i, long o) { 82 | name = n; 83 | libvideoID = i; 84 | resolutions = new ResolutionInfo(i,o); 85 | } 86 | 87 | /** 88 | * This method returns the {@link ResolutionInfo} object associated with 89 | * this image format. {@link ResolutionInfo} objects provide information 90 | * on supported capture resolutions and frame intervals. 91 | * @return the {@link ResolutionInfo} object associated with 92 | * this image format. 93 | */ 94 | public ResolutionInfo getResolutionInfo(){ 95 | return resolutions; 96 | } 97 | 98 | /** 99 | * This method returns the name of this image format. 100 | * @return the name of this format 101 | */ 102 | public String getName() { 103 | return name; 104 | } 105 | 106 | /** 107 | * This method returns the index for this format. 108 | * A list of all known format indexes can be found in {@link V4L4JConstants} 109 | * (V4L4JConstants.IMF_*). 110 | * @return the index of this format 111 | */ 112 | public int getIndex() { 113 | return libvideoID; 114 | } 115 | 116 | @Override 117 | public int hashCode() { 118 | final int prime = 31; 119 | int result = 1; 120 | result = prime * result + libvideoID; 121 | result = prime * result + ((name == null) ? 0 : name.hashCode()); 122 | return result; 123 | } 124 | 125 | @Override 126 | public boolean equals(Object obj) { 127 | if (this == obj) 128 | return true; 129 | if (obj == null) 130 | return false; 131 | if (!(obj instanceof ImageFormat)) 132 | return false; 133 | ImageFormat other = (ImageFormat) obj; 134 | if (libvideoID != other.libvideoID) 135 | return false; 136 | if (name == null) { 137 | if (other.name != null) 138 | return false; 139 | } else if (!name.equals(other.name)) 140 | return false; 141 | return true; 142 | } 143 | 144 | @Override 145 | public String toString(){ 146 | return name+" - "+libvideoID; 147 | } 148 | 149 | public String toNiceString(){ 150 | return name+" - "+libvideoID+" - "+resolutions; 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/Tuner.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2008 Gilles Gigan (gilles.gigan@gmail.com) 3 | * eResearch Centre, James Cook University (eresearch.jcu.edu.au) 4 | * 5 | * This program was developed as part of the ARCHER project 6 | * (Australian Research Enabling Environment) funded by a 7 | * Systemic Infrastructure Initiative (SII) grant and supported by the Australian 8 | * Department of Innovation, Industry, Science and Research 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17 | * or FITNESS FOR A PARTICULAR PURPOSE. 18 | * See the GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | * 23 | */ 24 | 25 | package au.edu.jcu.v4l4j; 26 | 27 | import au.edu.jcu.v4l4j.exceptions.StateException; 28 | 29 | /** 30 | * Instances of this class are used to represent a tuner attached to a 31 | * video input. Methods in this class control the frequency of the tuner 32 | * and report the received signal strength and the automatic frequency 33 | * control (when its value is negative, the frequency is too low and when 34 | * positive, it is too high). The AFC may not be available on all hardware. 35 | * If not, {@link #getAFC()} returns a value of 0.Tuners are not 36 | * directly instantiated. Instead, to retrieve the Tuner 37 | * associated with a frame grabber, call {@link FrameGrabber#getTuner()} 38 | * on the associated {@link FrameGrabber} object. Alternatively, you can also 39 | * obtain a list of {@link Tuner} objects by calling 40 | * {@link VideoDevice#getTunerList()}. 41 | * Methods in this class must not be called once the associated video device has 42 | * been released. Otherwise, a {@link StateException} will be thrown. 43 | * 44 | * @author gilles 45 | * 46 | */ 47 | public class Tuner { 48 | private long v4l4j_object; 49 | private TunerInfo info; 50 | private int index; 51 | 52 | private native long getFreq(long o, int i); 53 | private native void setFreq(long o, int i, long f); 54 | private native int getAfc(long o, int i); 55 | private native int getRssi(long o, int i); 56 | 57 | private boolean released; 58 | 59 | Tuner(long o, TunerInfo ti){ 60 | info = ti; 61 | index = info.getIndex(); 62 | v4l4j_object = o; 63 | released = false; 64 | } 65 | 66 | /** 67 | * This method returns the current frequency of this tuner. 68 | * @return the current frequency 69 | * @throws StateException if the associated frame grabber has been released 70 | * and this tuner must not be used anymore. 71 | */ 72 | public synchronized double getFrequency(){ 73 | checkRelease(); 74 | return getFreq(v4l4j_object, index)*0.0625; 75 | } 76 | 77 | /** 78 | * This method sets the frequency of this tuner. 79 | * @param f the new frequency 80 | * @throws StateException if the associated frame grabber has been released 81 | * and this tuner must not be used anymore. 82 | */ 83 | public synchronized void setFrequency(double f){ 84 | checkRelease(); 85 | long l = (long) (f/0.0625); 86 | setFreq(v4l4j_object, index, l); 87 | } 88 | 89 | /** 90 | * This method returns the current AFC (Automatic Frequency Control) value. 91 | * When its value is negative, the frequency is too low and when 92 | * positive, it is too high. 93 | * @return the current AFC value 94 | * @throws StateException if the associated frame grabber has been released 95 | * and this tuner must not be used anymore. 96 | */ 97 | public synchronized int getAFC() { 98 | checkRelease(); 99 | return getAfc(v4l4j_object, index); 100 | } 101 | 102 | /** 103 | * This method returns the current received signal strength. 104 | * @return the current received signal strength 105 | * @throws StateException if the associated frame grabber has been released 106 | * and this tuner must not be used anymore. 107 | */ 108 | public synchronized int getRSSI(){ 109 | checkRelease(); 110 | return getRssi(v4l4j_object, index); 111 | } 112 | 113 | /** 114 | * This method returns the index of this tuner. 115 | * @return the index of this tuner 116 | * @throws StateException if the associated frame grabber has been released 117 | * and this tuner must not be used anymore. 118 | */ 119 | public synchronized int getIndex(){ 120 | checkRelease(); 121 | return index; 122 | } 123 | 124 | /** 125 | * This method returns the {@link TunerInfo} object associated with this 126 | * tuner. 127 | * @return the {@link TunerInfo} object associated with this tuner. 128 | * @throws StateException if the associated frame grabber has been released 129 | * and this tuner must not be used anymore. 130 | */ 131 | public synchronized TunerInfo getInfo(){ 132 | checkRelease(); 133 | return info; 134 | } 135 | 136 | /** 137 | * This method releases this tuner. 138 | */ 139 | synchronized void release(){ 140 | released = true; 141 | } 142 | 143 | private void checkRelease(){ 144 | if(released) 145 | throw new StateException("The frame grabber associated with this " + 146 | "tuner has been already released and the tuner must not be " 147 | +"used anymore"); 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/PushSource.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Gilles Gigan (gilles.gigan@gmail.com) 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by the 6 | * Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 11 | * or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | package au.edu.jcu.v4l4j; 19 | 20 | import java.util.concurrent.ThreadFactory; 21 | 22 | import au.edu.jcu.v4l4j.exceptions.StateException; 23 | import au.edu.jcu.v4l4j.exceptions.V4L4JException; 24 | 25 | 26 | /** 27 | * PushSource instances create their own thread which polls 28 | * a frame grabber and notify the 29 | * {@link CaptureCallback} object given in the constructor 30 | * each time a new frame is available. 31 | * @author gilles 32 | * 33 | */ 34 | class PushSource implements Runnable { 35 | private CaptureCallback callback; 36 | private AbstractGrabber frameGrabber; 37 | private Thread thread; 38 | private ThreadFactory threadFactory; 39 | 40 | private int state; 41 | private static final int STATE_STOPPED = 0; 42 | private static final int STATE_RUNNING = 1; 43 | private static final int STATE_ABOUT_TO_STOP = 2; 44 | 45 | /** 46 | * This method builds a new PushSource instance 47 | * which will obtain frames from the given frame grabber and 48 | * pass them to the given callback object. 49 | * @param grabber the {@link FrameGrabber} instance on which 50 | * this push source will repeatedly call {@link FrameGrabber#getVideoFrame()}. 51 | * @param callback an object implementing the {@link CaptureCallback} 52 | * interface to which the frames will be delivered through the 53 | * {@link CaptureCallback#nextFrame(VideoFrame)}. 54 | */ 55 | public PushSource(AbstractGrabber grabber, CaptureCallback callback, ThreadFactory factory) { 56 | if ((grabber == null) || (callback == null)) 57 | throw new NullPointerException("the frame grabber and callback cannot be null"); 58 | 59 | this.callback = callback; 60 | frameGrabber = grabber; 61 | threadFactory = factory; 62 | state = STATE_STOPPED; 63 | } 64 | 65 | /** 66 | * This method instructs this source to start the capture and to push 67 | * to the captured frame to the 68 | * {@link CaptureCallback}. 69 | * @throws StateException if the capture has already been started 70 | */ 71 | public synchronized final long startCapture() throws V4L4JException{ 72 | if (state != STATE_STOPPED) 73 | throw new StateException("The capture has already been started"); 74 | 75 | // Update our state and start the thread 76 | state = STATE_RUNNING; 77 | thread = threadFactory.newThread(this); 78 | thread.setName(thread.getName() + " - v4l4j push source"); 79 | thread.start(); 80 | 81 | return thread.getId(); 82 | } 83 | 84 | /** 85 | * This method instructs this source to stop frame delivery 86 | * to the {@link CaptureCallback} object. 87 | * @throws StateException if the capture has already been stopped 88 | */ 89 | public final void stopCapture() { 90 | synchronized (this) { 91 | // make sure we are running 92 | if ((state == STATE_STOPPED) || (state == STATE_ABOUT_TO_STOP)) 93 | //throw new StateException("The capture is about to stop"); 94 | return; 95 | 96 | // update our state 97 | state = STATE_ABOUT_TO_STOP; 98 | } 99 | 100 | if (thread.isAlive()) { 101 | thread.interrupt(); 102 | 103 | // wait for thread to exit if the push thread is not the one 104 | // trying to join 105 | if (! Thread.currentThread().equals(thread)) { 106 | while (state == STATE_ABOUT_TO_STOP) { 107 | try { 108 | // wait for thread to exit 109 | thread.join(); 110 | //thread = null; 111 | } catch (InterruptedException e) { 112 | // interrupted while waiting for the thread to join 113 | // keep waiting 114 | // System.err.println("interrupted while waiting for frame pusher thread to complete"); 115 | // e.printStackTrace(); 116 | // throw new StateException("interrupted while waiting for frame pusher thread to complete", e); 117 | } 118 | } 119 | } 120 | 121 | } 122 | } 123 | 124 | @Override 125 | public final void run() { 126 | VideoFrame frame = null; 127 | 128 | while (! Thread.interrupted()){ 129 | try { 130 | // Get the next frame 131 | frame = frameGrabber.getNextVideoFrame(); 132 | 133 | // and deliver it to the callback object 134 | try { callback.nextFrame(frame); } 135 | catch (Throwable t) {} // ignore any exception thrown by the callback 136 | } catch (Throwable t) { 137 | // Received an exception. If we are in the middle of a capture (ie. it does not 138 | // happen as the result of the capture having been stopped or the frame 139 | // grabber released), then pass it on to the callback object. 140 | //e.printStackTrace(); 141 | try { 142 | if(frameGrabber.isStarted()) 143 | callback.exceptionReceived(new V4L4JException("Exception received while grabbing next frame", t)); 144 | } catch (Throwable t2) { 145 | // either the frame grabber has been released or the callback raised 146 | // an exception. do nothing, just exit. 147 | } 148 | // and make this thread exit 149 | Thread.currentThread().interrupt(); 150 | } 151 | } 152 | 153 | // update state 154 | state = STATE_STOPPED; 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/InputInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2008 Gilles Gigan (gilles.gigan@gmail.com) 3 | * eResearch Centre, James Cook University (eresearch.jcu.edu.au) 4 | * 5 | * This program was developed as part of the ARCHER project 6 | * (Australian Research Enabling Environment) funded by a 7 | * Systemic Infrastructure Initiative (SII) grant and supported by the Australian 8 | * Department of Innovation, Industry, Science and Research 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17 | * or FITNESS FOR A PARTICULAR PURPOSE. 18 | * See the GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | * 23 | */ 24 | package au.edu.jcu.v4l4j; 25 | 26 | import java.util.HashSet; 27 | import java.util.Set; 28 | 29 | import au.edu.jcu.v4l4j.exceptions.NoTunerException; 30 | 31 | /** 32 | * Objects of this class encapsulate information about a video input.
33 | *
    34 | *
  • The name of this input
  • 35 | *
  • The supported standards ({@link V4L4JConstants#STANDARD_PAL}, {@link V4L4JConstants#STANDARD_SECAM}, 36 | * {@link V4L4JConstants#STANDARD_NTSC} or {@link V4L4JConstants#STANDARD_WEBCAM})
  • 37 | *
  • The input type ({@link V4L4JConstants#INPUT_TYPE_TUNER} or 38 | * {@link V4L4JConstants#INPUT_TYPE_CAMERA})
  • 39 | *
  • The {@link TunerInfo} object associated with this input if it is 40 | * connected to a tuner.
  • 41 | *
42 | * You do not directly instantiate InputInfo objects. Instead, they 43 | * are created by the corresponding {@link VideoDevice} object through its 44 | * {@link VideoDevice#getDeviceInfo()} method. 45 | * @author gilles 46 | * 47 | */ 48 | public class InputInfo { 49 | /** 50 | * The name of this input 51 | */ 52 | private String name; 53 | 54 | /** 55 | * The type of this input 56 | */ 57 | private short type; 58 | 59 | /** 60 | * A set of the supported standards ({@link V4L4JConstants#STANDARD_PAL}, {@link V4L4JConstants#STANDARD_SECAM}, 61 | * {@link V4L4JConstants#STANDARD_NTSC} or {@link V4L4JConstants#STANDARD_WEBCAM}) 62 | */ 63 | private Set supportedStandards; 64 | 65 | /** 66 | * The tuner associated with this input, if any 67 | */ 68 | private TunerInfo tuner; 69 | 70 | /** 71 | * The V4L id associated with this input 72 | */ 73 | private int index; 74 | 75 | /** 76 | * This constructor builds an Input object representing a physical input on the V4L 77 | * video device. 78 | * @param n the name of the input 79 | * @param stds the supported standards 80 | * @param tun the tuner associated with this input if any 81 | */ 82 | private InputInfo(String n, int[] stds, short t, TunerInfo tun, int id){ 83 | tuner = tun; 84 | supportedStandards = new HashSet(); 85 | for(int s: stds) 86 | supportedStandards.add(new Integer(s)); 87 | type = t; 88 | name = n; 89 | index = id; 90 | } 91 | 92 | /** 93 | * This constructor builds an Input object representing a TUNER input on the V4L 94 | * video device. 95 | * @param n the name of the input 96 | * @param stds the supported standards 97 | * @param tun the tuner associated with this input 98 | */ 99 | InputInfo(String n, int[] stds, TunerInfo tun, int id){ 100 | this(n, stds, V4L4JConstants.INPUT_TYPE_TUNER, tun, id); 101 | } 102 | 103 | /** 104 | * This constructor builds an Input object representing a CAMERA input on the V4L 105 | * video device. 106 | * @param n the name of the input 107 | * @param stds the supported standards 108 | */ 109 | InputInfo(String n, int[] stds, int id){ 110 | this(n,stds,V4L4JConstants.INPUT_TYPE_CAMERA ,null, id); 111 | } 112 | 113 | /** 114 | * This method returns the name of this input 115 | * @return the name 116 | */ 117 | public String getName() { 118 | return name; 119 | } 120 | 121 | /** 122 | * This method returns the type of this input 123 | * ({@link V4L4JConstants#INPUT_TYPE_TUNER} or {@link V4L4JConstants#INPUT_TYPE_CAMERA}) 124 | * @return the type of this input 125 | */ 126 | public short getType() { 127 | return type; 128 | } 129 | 130 | /** 131 | * This method returns the standards supported by this input 132 | * ({@link V4L4JConstants#STANDARD_PAL}, {@link V4L4JConstants#STANDARD_SECAM}, 133 | * {@link V4L4JConstants#STANDARD_NTSC} or {@link V4L4JConstants#STANDARD_WEBCAM}) 134 | * @return the supportedStandards 135 | */ 136 | public Set getSupportedStandards() { 137 | return supportedStandards; 138 | } 139 | 140 | /** 141 | * This method returns the {@link TunerInfo} associated with this input, if any. 142 | * @return the tuner 143 | * @throws NoTunerException if this input is of type 144 | * {@link V4L4JConstants#INPUT_TYPE_CAMERA}, and is not a tuner. 145 | */ 146 | public TunerInfo getTunerInfo() throws NoTunerException{ 147 | if(tuner==null) 148 | throw new NoTunerException("No tuner connected to this input"); 149 | 150 | return tuner; 151 | } 152 | 153 | /** 154 | * This method returns a boolean depending on whether this input 155 | * has a tuner or not. 156 | * @return true if this input has a tuner, false otherwise 157 | */ 158 | public boolean hasTuner() { 159 | return tuner == null ? false : true; 160 | } 161 | 162 | /** 163 | * This method returns the (V4L) index of this input 164 | * @return the (V4L) index of this input 165 | */ 166 | public int getIndex(){ 167 | return index; 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/YUVFrameGrabber.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2008 Gilles Gigan (gilles.gigan@gmail.com) 3 | * eResearch Centre, James Cook University (eresearch.jcu.edu.au) 4 | * 5 | * This program was developed as part of the ARCHER project 6 | * (Australian Research Enabling Environment) funded by a 7 | * Systemic Infrastructure Initiative (SII) grant and supported by the Australian 8 | * Department of Innovation, Industry, Science and Research 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17 | * or FITNESS FOR A PARTICULAR PURPOSE. 18 | * See the GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | * 23 | */ 24 | package au.edu.jcu.v4l4j; 25 | 26 | import java.util.concurrent.ThreadFactory; 27 | 28 | import au.edu.jcu.v4l4j.exceptions.CaptureChannelException; 29 | import au.edu.jcu.v4l4j.exceptions.ImageFormatException; 30 | import au.edu.jcu.v4l4j.exceptions.InitialisationException; 31 | import au.edu.jcu.v4l4j.exceptions.StateException; 32 | import au.edu.jcu.v4l4j.exceptions.V4L4JException; 33 | import au.edu.jcu.v4l4j.exceptions.VideoStandardException; 34 | 35 | /** 36 | * Objects of this class are used to retrieve YUV420-encoded frames from a 37 | * {@link VideoDevice}. A YUV420 frame grabber can only be 38 | * created if the associated video device can produce images in a format v4l4j 39 | * knows how to encode in YUV420. The {@link VideoDevice#supportYUVConversion()} 40 | * method can be used to find out whether a video device can have its images 41 | * YUV420-encoded by v4l4j, ie if a YUV420 frame grabber can be instantiated. 42 | * YUVFrameGrabber objects are not instantiated directly. 43 | * Instead, the 44 | * {@link VideoDevice#getYUVFrameGrabber(int, int, int, int)} 45 | * or 46 | * {@link VideoDevice#getYUVFrameGrabber(int, int, int, int, ImageFormat)} 47 | * method must be called on the associated {@link VideoDevice}. YUV frame grabbers 48 | * implement the {@link FrameGrabber} interface which provides methods to handle 49 | * video capture. See {@link FrameGrabber its documentation} for more information. 50 | * 51 | * @see FrameGrabber {@link FrameGrabber} 52 | * @author gilles 53 | * 54 | */ 55 | public class YUVFrameGrabber extends AbstractGrabber { 56 | /** 57 | * This constructor builds a FrameGrabber object used to capture YUV420 58 | * frames from a video source 59 | * @param di the DeviceInfo of the VideoDevice who created this frame grabber 60 | * @param o a JNI pointer to a v4l4j_device structure 61 | * @param w the requested frame width 62 | * @param h the requested frame height 63 | * @param ch the input index, as returned by 64 | * {@link InputInfo#getIndex()} 65 | * @param std the video standard, as returned by 66 | * {@link InputInfo#getSupportedStandards()} (see V4L4JConstants) 67 | * @param imf the image format frame should be captured in 68 | * @param factory the thread factory to use when creating the push source 69 | */ 70 | YUVFrameGrabber(DeviceInfo di, long o, int w, int h, int ch, int std, Tuner t, 71 | ImageFormat imf, ThreadFactory factory) throws ImageFormatException { 72 | super(di, o, w, h, ch, std, t, imf, YUV_GRABBER, factory); 73 | } 74 | 75 | /** 76 | * This method initialises the capture, and apply the capture parameters. 77 | * V4L may either adjust the height and width parameters to the closest 78 | * valid values or reject them altogether. If the values were adjusted, 79 | * they can be retrieved after calling {@link #init()} using 80 | * {@link #getWidth()} and {@link #getHeight()}. 81 | * @throws VideoStandardException if the chosen video standard is not 82 | * supported 83 | * @throws ImageFormatException this exception is thrown if the chosen image 84 | * format cannot be YUV420 encoded. If no image format was chosen, the video 85 | * device does not have any image formats that can be YUV420 encoded 86 | * (let the author know, see README file) 87 | * @throws CaptureChannelException if the given channel number value is not 88 | * valid 89 | * @throws ImageDimensionException if the given image dimensions are not 90 | * supported 91 | * @throws InitialisationException if the video device file can not be 92 | * initialised 93 | * @throws StateException if the frame grabber is already initialised or 94 | * released 95 | * @throws V4L4JException if there is an error applying capture parameters 96 | */ 97 | void init() throws V4L4JException{ 98 | try { 99 | super.init(); 100 | } catch (ImageFormatException ife){ 101 | if(format == -1){ 102 | String msg = 103 | "v4l4j was unable to find image format supported by the" 104 | + " \nvideo device and that can be converted to YUV420.\n" 105 | + "Please let the author know about this, so that support\n" 106 | + "for this video device can be improved. See \nREADME file" 107 | + " on how to submit v4l4j reports."; 108 | System.err.println(msg); 109 | ife = new ImageFormatException(msg); 110 | } 111 | 112 | throw ife; 113 | } 114 | } 115 | 116 | /** 117 | * This method returns the native image format used by this 118 | * FrameGrabber. The returned format specifies the image format the capture 119 | * uses, ie the one images are retrieved from the device BEFORE YUV 120 | * conversion. 121 | * @return the native image format used by this FrameGrabber. 122 | * @throws StateException if this 123 | * FrameGrabber has been already released, and therefore must 124 | * not be used anymore. 125 | */ 126 | public ImageFormat getImageFormat(){ 127 | state.checkReleased(); 128 | return dInfo.getFormatList().getYUVEncodableFormat(format); 129 | } 130 | 131 | @Override 132 | protected void createBuffers(int bufferSize) { 133 | int numberOfBuffers = nbV4LBuffers; 134 | 135 | while(numberOfBuffers-- > 0) 136 | // TODO: fix me, find a way to create a writable raster 137 | // and BufferedImage for planar YUV420 image format 138 | videoFrames.add( new UncompressedVideoFrame(this, bufferSize, null, null) ); 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/YVUFrameGrabber.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2008 Gilles Gigan (gilles.gigan@gmail.com) 3 | * eResearch Centre, James Cook University (eresearch.jcu.edu.au) 4 | * 5 | * This program was developed as part of the ARCHER project 6 | * (Australian Research Enabling Environment) funded by a 7 | * Systemic Infrastructure Initiative (SII) grant and supported by the Australian 8 | * Department of Innovation, Industry, Science and Research 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17 | * or FITNESS FOR A PARTICULAR PURPOSE. 18 | * See the GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | * 23 | */ 24 | package au.edu.jcu.v4l4j; 25 | 26 | import java.util.concurrent.ThreadFactory; 27 | 28 | import au.edu.jcu.v4l4j.exceptions.CaptureChannelException; 29 | import au.edu.jcu.v4l4j.exceptions.ImageFormatException; 30 | import au.edu.jcu.v4l4j.exceptions.InitialisationException; 31 | import au.edu.jcu.v4l4j.exceptions.StateException; 32 | import au.edu.jcu.v4l4j.exceptions.V4L4JException; 33 | import au.edu.jcu.v4l4j.exceptions.VideoStandardException; 34 | 35 | /** 36 | * Objects of this class are used to retrieve YVU420-encoded frames from a 37 | * {@link VideoDevice}. A YVU420 frame grabber can only be 38 | * created if the associated video device can produce images in a format v4l4j 39 | * knows how to encode in YVU420. The {@link VideoDevice#supportYVUConversion()} 40 | * method can be used to find out whether a video device can have its images 41 | * YVU420-encoded by v4l4j, ie if a YVU420 frame grabber can be instantiated. 42 | * YVUFrameGrabber objects are not instantiated directly. 43 | * Instead, the 44 | * {@link VideoDevice#getYVUFrameGrabber(int, int, int, int)} 45 | * or 46 | * {@link VideoDevice#getYVUFrameGrabber(int, int, int, int, ImageFormat)} 47 | * method must be called on the associated {@link VideoDevice}. YVU frame grabbers 48 | * implement the {@link FrameGrabber} interface which provides methods to handle 49 | * video capture. See {@link FrameGrabber its documentation} for more information. 50 | * 51 | * @see FrameGrabber {@link FrameGrabber} 52 | * @author gilles 53 | * 54 | */ 55 | public class YVUFrameGrabber extends AbstractGrabber { 56 | /** 57 | * This constructor builds a FrameGrabber object used to capture YVU420 58 | * frames from a video source 59 | * @param di the DeviceInfo of the VideoDevice who created this frame grabber 60 | * @param o a JNI pointer to a v4l4j_device structure 61 | * @param w the requested frame width 62 | * @param h the requested frame height 63 | * @param ch the input index, as returned by 64 | * {@link InputInfo#getIndex()} 65 | * @param std the video standard, as returned by 66 | * {@link InputInfo#getSupportedStandards()} (see V4L4JConstants) 67 | * @param imf the image format frame should be captured in 68 | * @param factory the thread factory to use when creating the push source. 69 | */ 70 | YVUFrameGrabber(DeviceInfo di,long o, int w, int h, int ch, int std, Tuner t, 71 | ImageFormat imf, ThreadFactory factory) throws ImageFormatException { 72 | super(di, o, w, h, ch, std, t, imf, YVU_GRABBER, factory); 73 | } 74 | 75 | /** 76 | * This method initialises the capture, and apply the capture parameters. 77 | * V4L may either adjust the height and width parameters to the closest 78 | * valid values or reject them altogether. If the values were adjusted, 79 | * they can be retrieved after calling {@link #init()} using 80 | * {@link #getWidth()} and {@link #getHeight()}. 81 | * @throws VideoStandardException if the chosen video standard is not 82 | * supported 83 | * @throws ImageFormatException this exception is thrown if the chosen image 84 | * format cannot be YVU420 encoded. If no image format was chosen, the video 85 | * device does not have any image formats that can be YVU420 encoded 86 | * (let the author know, see README file) 87 | * @throws CaptureChannelException if the given channel number value is not 88 | * valid 89 | * @throws ImageDimensionException if the given image dimensions are not 90 | * supported 91 | * @throws InitialisationException if the video device file can not be 92 | * initialised 93 | * @throws StateException if the frame grabber is already initialised or 94 | * released 95 | * @throws V4L4JException if there is an error applying capture parameters 96 | */ 97 | void init() throws V4L4JException{ 98 | try { 99 | super.init(); 100 | } catch (ImageFormatException ife){ 101 | if(format == -1){ 102 | String msg = 103 | "v4l4j was unable to find image format supported by the" 104 | + " \nvideo device and that can be converted to YVU420.\n" 105 | + "Please let the author know about this, so that support\n" 106 | + "for this video device can be improved. See \nREADME file" 107 | + " on how to submit v4l4j reports."; 108 | System.err.println(msg); 109 | ife = new ImageFormatException(msg); 110 | } 111 | 112 | throw ife; 113 | } 114 | } 115 | 116 | /** 117 | * This method returns the native image format used by this 118 | * FrameGrabber. The returned format specifies the image format the capture 119 | * uses, ie the one images are retrieved from the device BEFORE YVU 120 | * conversion. 121 | * @return the native image format used by this FrameGrabber. 122 | * @throws StateException if this 123 | * FrameGrabber has been already released, and therefore must 124 | * not be used anymore. 125 | */ 126 | public ImageFormat getImageFormat(){ 127 | state.checkReleased(); 128 | return dInfo.getFormatList().getYVUEncodableFormat(format); 129 | } 130 | 131 | 132 | @Override 133 | protected void createBuffers(int bufferSize) { 134 | int numberOfBuffers = nbV4LBuffers; 135 | 136 | while(numberOfBuffers-- > 0) 137 | // TODO: fix me, find a way to create a writable raster 138 | // and BufferedImage for planar YVU420 image format 139 | videoFrames.add( new UncompressedVideoFrame(this, bufferSize, null, null) ); 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/BGRFrameGrabber.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2008 Gilles Gigan (gilles.gigan@gmail.com) 3 | * eResearch Centre, James Cook University (eresearch.jcu.edu.au) 4 | * 5 | * This program was developed as part of the ARCHER project 6 | * (Australian Research Enabling Environment) funded by a 7 | * Systemic Infrastructure Initiative (SII) grant and supported by the Australian 8 | * Department of Innovation, Industry, Science and Research 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17 | * or FITNESS FOR A PARTICULAR PURPOSE. 18 | * See the GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | * 23 | */ 24 | package au.edu.jcu.v4l4j; 25 | 26 | import java.awt.color.ColorSpace; 27 | import java.awt.image.DataBuffer; 28 | import java.awt.image.PixelInterleavedSampleModel; 29 | import java.util.concurrent.ThreadFactory; 30 | 31 | import au.edu.jcu.v4l4j.exceptions.CaptureChannelException; 32 | import au.edu.jcu.v4l4j.exceptions.ImageFormatException; 33 | import au.edu.jcu.v4l4j.exceptions.InitialisationException; 34 | import au.edu.jcu.v4l4j.exceptions.StateException; 35 | import au.edu.jcu.v4l4j.exceptions.V4L4JException; 36 | import au.edu.jcu.v4l4j.exceptions.VideoStandardException; 37 | 38 | /** 39 | * Objects of this class are used to retrieve BGR24-encoded frames from a 40 | * {@link VideoDevice}. A BGR24 frame grabber can only be created 41 | * if the associated video device can produce images in a format v4l4j 42 | * knows how to encode in BGR24. The {@link VideoDevice#supportBGRConversion()} 43 | * method can be used to find out whether a video device can have its images 44 | * BGR24-encoded by v4l4j, ie if a BGR24 frame grabber can be instantiated. 45 | * BGRFrameGrabber objects are not instantiated directly. 46 | * Instead, the 47 | * {@link VideoDevice#getBGRFrameGrabber(int, int, int, int)} 48 | * or 49 | * {@link VideoDevice#getBGRFrameGrabber(int, int, int, int, ImageFormat)} 50 | * method must be called on the associated {@link VideoDevice}. 51 | * BGR frame grabbers 52 | * implement the {@link FrameGrabber} interface which provides methods to handle 53 | * video capture. See {@link FrameGrabber its documentation} for more information. 54 | * 55 | * @see FrameGrabber {@link FrameGrabber} 56 | * @author gilles 57 | * 58 | */ 59 | public class BGRFrameGrabber extends AbstractGrabber { 60 | 61 | /** 62 | * This constructor builds a FrameGrabber object used to capture BGR24 63 | * frames from a video source 64 | * @param di the DeviceInfo of the video device 65 | * @param o a JNI pointer to a v4l4j_device structure 66 | * @param w the requested frame width 67 | * @param h the requested frame height 68 | * @param ch the input index, as returned by 69 | * {@link InputInfo#getIndex()} 70 | * @param std the video standard, as returned by 71 | * {@link InputInfo#getSupportedStandards()} (see V4L4JConstants) 72 | * @param imf the image format frame should be captured in 73 | * @param factory the thread factory to use when creating the push source thread. 74 | */ 75 | BGRFrameGrabber(DeviceInfo di, long o, int w, int h, int ch, int std, 76 | Tuner t,ImageFormat imf, ThreadFactory factory) throws ImageFormatException { 77 | super(di, o, w, h, ch, std, t, imf, BGR24_GRABBER, factory); 78 | } 79 | 80 | /** 81 | * This method initialises the capture, and apply the capture parameters. 82 | * V4L may either adjust the height and width parameters to the closest 83 | * valid values or reject them altogether. If the values were adjusted, 84 | * they can be retrieved after calling {@link #init()} using 85 | * {@link #getWidth()} and {@link #getHeight()}. 86 | * @throws VideoStandardException if the chosen video standard is not 87 | * supported 88 | * @throws ImageFormatException this exception is thrown if the chosen image 89 | * format cannot be BGR24 encoded. If no image format was chosen, the video 90 | * device does not have any image formats that can be BGR24 encoded 91 | * (let the author know, see README file) 92 | * @throws CaptureChannelException if the given channel number value is not 93 | * valid 94 | * @throws ImageDimensionException if the given image dimensions are not 95 | * supported 96 | * @throws InitialisationException if the video device file can not be 97 | * initialised 98 | * @throws StateException if the frame grabber is already initialised 99 | * or released 100 | * @throws V4L4JException if there is an error applying capture parameters 101 | */ 102 | void init() throws V4L4JException{ 103 | try { 104 | super.init(); 105 | } catch (ImageFormatException ife){ 106 | if(format == -1){ 107 | String msg = 108 | "v4l4j was unable to find image format supported by the" 109 | + " \nvideo device and that can be converted to BGR24.\n" 110 | + "Please let the author know about this, so that support\n" 111 | + "for this video device can be improved. See \nREADME file" 112 | + " on how to submit v4l4j reports."; 113 | System.err.println(msg); 114 | ife = new ImageFormatException(msg); 115 | } 116 | 117 | throw ife; 118 | } 119 | } 120 | 121 | /** 122 | * This method returns the native image format used by this 123 | * FrameGrabber. The returned format specifies the image format the capture 124 | * uses, ie the one images are retrieved from the device BEFORE BGR 125 | * conversion. 126 | * @return the native image format used by this FrameGrabber. 127 | * @throws StateException if this 128 | * FrameGrabber has been already released, and therefore must 129 | * not be used anymore. 130 | */ 131 | public ImageFormat getImageFormat(){ 132 | state.checkReleased(); 133 | return dInfo.getFormatList().getBGREncodableFormat(format); 134 | } 135 | 136 | @Override 137 | protected void createBuffers(int bufferSize) { 138 | int numberOfBuffers = nbV4LBuffers; 139 | ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB); 140 | PixelInterleavedSampleModel sm = new PixelInterleavedSampleModel( 141 | DataBuffer.TYPE_BYTE, getWidth(), getHeight(), 3, getWidth() * 3, new int[] {2,1,0}); 142 | 143 | while(numberOfBuffers-- > 0) 144 | videoFrames.add( new UncompressedVideoFrame(this, bufferSize, sm, cs) ); 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/RGBFrameGrabber.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2008 Gilles Gigan (gilles.gigan@gmail.com) 3 | * eResearch Centre, James Cook University (eresearch.jcu.edu.au) 4 | * 5 | * This program was developed as part of the ARCHER project 6 | * (Australian Research Enabling Environment) funded by a 7 | * Systemic Infrastructure Initiative (SII) grant and supported by the Australian 8 | * Department of Innovation, Industry, Science and Research 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17 | * or FITNESS FOR A PARTICULAR PURPOSE. 18 | * See the GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | * 23 | */ 24 | package au.edu.jcu.v4l4j; 25 | 26 | import java.awt.color.ColorSpace; 27 | import java.awt.image.DataBuffer; 28 | import java.awt.image.PixelInterleavedSampleModel; 29 | import java.util.concurrent.ThreadFactory; 30 | 31 | import au.edu.jcu.v4l4j.exceptions.CaptureChannelException; 32 | import au.edu.jcu.v4l4j.exceptions.ImageFormatException; 33 | import au.edu.jcu.v4l4j.exceptions.InitialisationException; 34 | import au.edu.jcu.v4l4j.exceptions.StateException; 35 | import au.edu.jcu.v4l4j.exceptions.V4L4JException; 36 | import au.edu.jcu.v4l4j.exceptions.VideoStandardException; 37 | 38 | 39 | /** 40 | * Objects of this class are used to retrieve RGB frames from a 41 | * {@link VideoDevice}. An RGB frame grabber can only be created 42 | * if the associated video device can produce images in a format v4l4j 43 | * knows how to convert to RGB24. The 44 | * {@link VideoDevice#supportRGBConversion()} method can be used to find out 45 | * whether a video device can have its images RGB-encoded by v4l4j, ie if a 46 | * RGB frame grabber can be instantiated. 47 | * RGBFrameGrabber objects are not instantiated directly. Instead, 48 | * the 49 | * {@link VideoDevice#getRGBFrameGrabber(int, int, int, int)} or 50 | * {@link VideoDevice#getRGBFrameGrabber(int, int, int, int, ImageFormat)} 51 | * method must be called on the associated {@link VideoDevice}. RGB frame grabbers 52 | * implement the {@link FrameGrabber} interface which provides methods to handle 53 | * video capture. See {@link FrameGrabber its documentation} for more information. 54 | * 55 | * @see FrameGrabber {@link FrameGrabber} 56 | * @author gilles 57 | * 58 | */ 59 | public class RGBFrameGrabber extends AbstractGrabber { 60 | 61 | /** 62 | * This constructor builds a FrameGrabber object used to capture RGB frames 63 | * from a video source 64 | * @param di the DeviceInfo of the VideoDevice who created this frame grabber 65 | * @param o a JNI pointer to a v4l4j_device structure 66 | * @param w the requested frame width 67 | * @param h the requested frame height 68 | * @param ch the input index, as returned by 69 | * {@link InputInfo#getIndex()} 70 | * @param std the video standard, as returned by 71 | * {@link InputInfo#getSupportedStandards()} (see V4L4JConstants) 72 | * @param imf the image format frame should be captured in 73 | * @param factory the thread factory to use when creating the push source 74 | */ 75 | RGBFrameGrabber(DeviceInfo di, long o, int w, int h, int ch, int std, Tuner t, 76 | ImageFormat imf, ThreadFactory factory) throws V4L4JException{ 77 | super(di, o,w,h,ch,std, t , imf, RGB24_GRABBER, factory); 78 | } 79 | 80 | /** 81 | * This method initialises the capture, and apply the capture parameters. 82 | * V4L may either adjust the height and width parameters to the closest 83 | * valid values or reject them altogether. If the values were adjusted, 84 | * they can be retrieved after calling {@link #init()} using 85 | * {@link #getWidth()} and {@link #getHeight()}. 86 | * @throws VideoStandardException if the chosen video standard is not 87 | * supported 88 | * @throws ImageFormatException this exception is thrown if the chosen image 89 | * format cannot be RGB24 encoded. If no image format was chosen, the video 90 | * device does not have any image formats that can be RGB24 encoded 91 | * (let the author know, see README file) 92 | * @throws CaptureChannelException if the given channel number value is not 93 | * valid 94 | * @throws ImageDimensionException if the given image dimensions are not 95 | * supported 96 | * @throws InitialisationException if the video device file can not be 97 | * initialised 98 | * @throws StateException if the frame grabber is already initialised or 99 | * released 100 | * @throws V4L4JException if there is an error applying capture parameters 101 | */ 102 | void init() throws V4L4JException{ 103 | try { 104 | super.init(); 105 | } catch (ImageFormatException ife){ 106 | if(format == -1){ 107 | String msg = 108 | "v4l4j was unable to find image format supported by the" 109 | + " \nvideo device and that can be converted to RGB24.\n" 110 | + "Please let the author know about this, so that support\n" 111 | + "for this video device can be improved. See \nREADME file" 112 | + " on how to submit v4l4j reports."; 113 | System.err.println(msg); 114 | ife = new ImageFormatException(msg); 115 | } 116 | 117 | throw ife; 118 | } 119 | } 120 | 121 | /** 122 | * This method returns the native image format used by this 123 | * FrameGrabber. The returned format specifies the image format the capture 124 | * uses, ie the one images are retrieved from the device BEFORE RGB 125 | * conversion. 126 | * @return the native image format used by this FrameGrabber. 127 | * @throws StateException if this 128 | * FrameGrabber has been already released, and therefore must 129 | * not be used anymore. 130 | */ 131 | public ImageFormat getImageFormat(){ 132 | state.checkReleased(); 133 | return dInfo.getFormatList().getRGBEncodableFormat(format); 134 | } 135 | 136 | @Override 137 | protected void createBuffers(int bufferSize) { 138 | ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB); 139 | PixelInterleavedSampleModel sm = new PixelInterleavedSampleModel( 140 | DataBuffer.TYPE_BYTE, getWidth(), getHeight(), 3, getWidth() * 3, new int[] {0,1,2}); 141 | 142 | int numberOfBuffers = nbV4LBuffers; 143 | 144 | while(numberOfBuffers-- > 0) 145 | videoFrames.add( new UncompressedVideoFrame(this, bufferSize, sm, cs) ); 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | *

Video4Linux4java Main Package

3 | *

Introduction

4 | * The Video4Linux (V4L) API provides data structures & methods to access and control 5 | * video input & output hardware, as well as radio tuners. The API is divided into 6 | * several interfaces, including video capture, video overlay, video output & 7 | * teletext interfaces. v4l4j provides access to the video capture 8 | * interface of V4L only. v4l4j allows you to retrieve information about a video 9 | * device, access its video controls & tuners and grab images from it.
10 | * 11 | *

Examples

12 | * v4l4j comes with many simple, easy-to-follow example applications in the 13 | * au.edu.jcu.v4l4j.examples package. It is strongly suggested you take a look 14 | * at them as you read these JavaDoc pages as they help illustrate concepts 15 | * crucial to a correct use of this API. 16 | *

Usage

17 | *

Video device object

18 | * To use v4l4j, the first step is to create a {@link au.edu.jcu.v4l4j.VideoDevice} 19 | * object, which represents a physical video input hardware device. This includes webcams 20 | * and capture / tuner cards. The only pre-requisite is that your hardware must be 21 | * supported and its driver loaded. Creating a {@link au.edu.jcu.v4l4j.VideoDevice} 22 | * is simple. You only need the path to a valid device file to create this object:
23 | * 24 | * VideoDevice vd = new VideoDevice("/dev/video0"); 25 | *
26 | * As it is the case most of the time when interacting with hardware, you must 27 | * release resources and data structures when finished. All v4l4j classes follow 28 | * this rule, including {@link au.edu.jcu.v4l4j.VideoDevice}s. The rare exceptions 29 | * are clearly identified in their java documentation.
30 | * 31 | * vd.release();
32 | * Once an object has been release()d, it must not be reused, and 33 | * all references to it must be discarded, by explicitly setting them to 34 | * null for example. Calling any release() method more 35 | * than once will throw a 36 | * {@link au.edu.jcu.v4l4j.exceptions.StateException StateException}. 37 | *
38 | * {@link au.edu.jcu.v4l4j.VideoDevice} objects give you access to 4 broad 39 | * categories: 40 | *
    41 | *
  • information about the underlying hardware through 42 | * {@link au.edu.jcu.v4l4j.DeviceInfo} objects,
  • 43 | *
  • a variety of controls through {@link au.edu.jcu.v4l4j.ControlList} 44 | * objects, and
  • 45 | *
  • a frame capture facility using {@link au.edu.jcu.v4l4j.FrameGrabber} 46 | * objects.
  • 47 | *
  • an interface to control any tuners, using {@link au.edu.jcu.v4l4j.TunerList} 48 | * objects. 49 | *
50 | * Each of these can be obtained independently from each other, by calling 51 | * the appropriate method on a {@link au.edu.jcu.v4l4j.VideoDevice} instance. 52 | * This flexibility allows an application to create a GUI which provides access 53 | * to video controls, while another application is streaming video from the 54 | * device. For this to work, the device driver must allows multiple applications 55 | * to open the device file simultaneously. As an example, the UVC driver works 56 | * this way. 57 | *

Video hardware information

58 | * With a valid {@link au.edu.jcu.v4l4j.VideoDevice} object, you 59 | * can retrieve information about 60 | * the underlying hardware and find out, for example how many video inputs the 61 | * device has, how many tuners are available, the set of supported video 62 | * standards and capture resolutions. This kind of information is contained in a 63 | * {@link au.edu.jcu.v4l4j.DeviceInfo} object. You can get a reference to a 64 | * {@link au.edu.jcu.v4l4j.DeviceInfo} object for a given video device by calling 65 | * {@link au.edu.jcu.v4l4j.VideoDevice#getDeviceInfo()} on the 66 | * {@link au.edu.jcu.v4l4j.VideoDevice} object. See the documentation of the 67 | * {@link au.edu.jcu.v4l4j.VideoDevice} and {@link au.edu.jcu.v4l4j.DeviceInfo} 68 | * classes for more information. 69 | * 70 | *

Video controls

71 | * Video capture devices usually have a set of controls which influence 72 | * various parameters related to the video stream. Examples are brightness, 73 | * contrast, gamma & white balance. A single control is represented by 74 | * {@link au.edu.jcu.v4l4j.Control} object. The set of supported controls for 75 | * a given video device hardware-dependent and is embedded into a 76 | * {@link au.edu.jcu.v4l4j.ControlList} object, which can be obtained by calling 77 | * {@link au.edu.jcu.v4l4j.VideoDevice#getControlList()}. The 78 | * {@link au.edu.jcu.v4l4j.ControlList} object must be released when controls 79 | * are no longer needed. This is done by calling 80 | * {@link au.edu.jcu.v4l4j.VideoDevice#releaseControlList()}. Again, once released, 81 | * neither the {@link au.edu.jcu.v4l4j.ControlList} nor individual 82 | * {@link au.edu.jcu.v4l4j.Control}s must be used, and any reference to them 83 | * must be discarded, by explicitly setting them to null for example. 84 | * For more information, check the documentation of the 85 | * {@link au.edu.jcu.v4l4j.Control} and {@link au.edu.jcu.v4l4j.ControlList} classes. 86 | * 87 | *

Video capture

88 | * Capture in v4l4j is extremely simple. v4l4j hands out captured frames in a 89 | * {@link au.edu.jcu.v4l4j.VideoFrame} object, either in a native image format ( 90 | * also referred to as raw format in v4l4j's documentation) or one of the 5 convenience 91 | * image formats (JPEG, RGB24, BGR24, YUV420 or YVU420). Each of these 6 image 92 | * formats is output by a dedicated frame grabber object, which will grab frames and 93 | * convert them to that format if required. 94 | * 95 | * The set of native {@link au.edu.jcu.v4l4j.ImageFormat}s supported by a video 96 | * device can be obtained using the {@link au.edu.jcu.v4l4j.DeviceInfo} object 97 | * (see paragraph "Video hardware information" above). 98 | * When capturing in a native format, v4l4j simply hands out the 99 | * captured frame without further processing. When capturing in one of the 100 | * convenience formats, v4l4j will transparently convert the image.
101 | * Frame grabbers operate in push mode: the frame grabber 102 | * delivers captured frames to a callback object you provide. 103 | * 104 | * Frame capture in v4l4j is done using objects implementing the 105 | * {@link au.edu.jcu.v4l4j.FrameGrabber} interface. Check the documentation 106 | * of the {@link au.edu.jcu.v4l4j.FrameGrabber} class for more information. 107 | * 108 | *

Tuners

109 | * v4l4j provides access to tuners if present in the video device. A 110 | * {@link au.edu.jcu.v4l4j.TunerList} object can be obtained by calling 111 | * {@link au.edu.jcu.v4l4j.VideoDevice#getTunerList()}. Note that the tuner list 112 | * need not be released when finished. 113 | */ 114 | package au.edu.jcu.v4l4j; 115 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/BaseVideoFrame.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Gilles Gigan (gilles.gigan@gmail.com) 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by the 6 | * Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 11 | * or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | package au.edu.jcu.v4l4j; 19 | 20 | import java.awt.image.BufferedImage; 21 | import java.awt.image.DataBuffer; 22 | import java.awt.image.WritableRaster; 23 | 24 | import au.edu.jcu.v4l4j.exceptions.StateException; 25 | import au.edu.jcu.v4l4j.exceptions.UnsupportedMethod; 26 | 27 | /** 28 | * This is the base class for all {@link VideoFrame} objects. 29 | * It implements some of the functionalities shared by all video frames. 30 | * It must be subclassed - and subclasses are responsible for instantiating the 31 | * raster and bufferedImage members 32 | * @author gilles 33 | * 34 | */ 35 | class BaseVideoFrame implements VideoFrame{ 36 | protected int frameLength; 37 | protected AbstractGrabber frameGrabber; 38 | protected byte frameBuffer[]; 39 | 40 | protected long sequenceNumber; 41 | protected long captureTime; 42 | protected int bufferIndex; 43 | 44 | protected V4L4JDataBuffer dataBuffer; 45 | protected boolean recycled; 46 | protected V4L4JRaster raster; 47 | protected BufferedImage bufferedImage; 48 | 49 | 50 | /** 51 | * This method creates the base for a video frame. It will instantiate 52 | * and initialise all members except raster and bufferedImage, which 53 | * falls under the responsibility of the subclass. 54 | * @param grabber the frame grabber to which this frame must be 55 | * returned to when recycled. 56 | * @param bufferSize the size of the byte array to create for this frame. 57 | */ 58 | protected BaseVideoFrame(AbstractGrabber grabber, int bufferSize) { 59 | frameGrabber = grabber; 60 | frameBuffer = new byte[bufferSize]; 61 | dataBuffer = new V4L4JDataBuffer(frameBuffer); 62 | raster = null; 63 | bufferedImage = null; 64 | bufferIndex = 0; 65 | recycled = true; 66 | } 67 | 68 | /** 69 | * This method marks this frame as ready to be delivered to the user, as its 70 | * buffer has just been filled with a new frame of the given length. 71 | * @param length the length of the new frame. 72 | * @param sequence this frame's sequence number 73 | * @param timeUs this frame capture timestamp in elapsed microseconds since startup 74 | */ 75 | final synchronized void prepareForDelivery(int length, int index, 76 | long sequence, long timeUs){ 77 | frameLength = length; 78 | dataBuffer.setNewFrameSize(length); 79 | sequenceNumber = sequence; 80 | captureTime = timeUs; 81 | bufferIndex = index; 82 | recycled = false; 83 | } 84 | 85 | /** 86 | * This method is used by the owning frame grabber so it can wait until 87 | * this frame is recycled. 88 | * @throws InterruptedException if we were interrupted while waiting 89 | * for the frame to be recycled. 90 | */ 91 | final synchronized void waitTillRecycled() throws InterruptedException { 92 | while(! recycled) 93 | wait(); 94 | } 95 | 96 | /** 97 | * This method is used by the owning frame grabber to get a reference 98 | * to the byte array used to hold the frame data. 99 | * @return the byte array used to hold the frame data 100 | */ 101 | final byte[] getByteArray() { 102 | return frameBuffer; 103 | } 104 | 105 | /** 106 | * This method is used by the owning frame grabber to get the V4L2 buffer 107 | * index 108 | * @return the V4L2 buffer index 109 | */ 110 | final int getBufferInex() { 111 | return bufferIndex; 112 | } 113 | 114 | /** 115 | * Subclasses can override this method to either 116 | * return a {@link WritableRaster} for this video frame, or throw 117 | * a {@link UnsupportedMethod} exception if this video frame cannot 118 | * generate a {@link WritableRaster}. 119 | * @return a {@link WritableRaster}. 120 | * @throws UnsupportedMethod exception if a raster cannot be generated 121 | * for this video frame (because of its image format for instance) 122 | */ 123 | protected WritableRaster refreshRaster() { 124 | if (raster == null) 125 | throw new UnsupportedMethod("A raster can not be generated for this " 126 | + "image format ("+frameGrabber.getImageFormat().toString()+")"); 127 | 128 | return raster; 129 | } 130 | 131 | /** 132 | * Subclasses can override this method to either 133 | * return a {@link BufferedImage} for this video frame, or throw 134 | * a {@link UnsupportedMethod} exception if this video frame cannot 135 | * generate a {@link BufferedImage}. 136 | * @return a {@link BufferedImage}. 137 | * @throws UnsupportedMethod exception if a buffered image cannot be generated 138 | * for this video frame (because of its image format for instance) 139 | */ 140 | protected BufferedImage refreshBufferedImage() { 141 | if (bufferedImage == null) 142 | throw new UnsupportedMethod("A Bufferedimage can not be generated for this " 143 | + "image format ("+frameGrabber.getImageFormat().toString()+")"); 144 | 145 | return bufferedImage; 146 | } 147 | 148 | /** 149 | * This method must be called with this video frame lock held, and 150 | * throws a {@link StateException} if it is recycled. 151 | * @throws StateException if this video frame is recycled. 152 | */ 153 | private final void checkIfRecycled() throws StateException { 154 | if (recycled) 155 | throw new StateException("This video frame has been recycled"); 156 | } 157 | 158 | 159 | /* 160 | * 161 | * Video Frame interface methods 162 | * 163 | */ 164 | @Override 165 | public final FrameGrabber getFrameGrabber() { 166 | return frameGrabber; 167 | } 168 | 169 | @Override 170 | public final synchronized int getFrameLength(){ 171 | checkIfRecycled(); 172 | return frameLength; 173 | } 174 | 175 | @Override 176 | public final synchronized byte[] getBytes(){ 177 | checkIfRecycled(); 178 | return frameBuffer; 179 | } 180 | 181 | @Override 182 | public final synchronized DataBuffer getDataBuffer() { 183 | checkIfRecycled(); 184 | return dataBuffer; 185 | } 186 | 187 | @Override 188 | public final synchronized WritableRaster getRaster() { 189 | checkIfRecycled(); 190 | return refreshRaster(); 191 | } 192 | 193 | @Override 194 | public final synchronized BufferedImage getBufferedImage(){ 195 | checkIfRecycled(); 196 | return refreshBufferedImage(); 197 | } 198 | 199 | @Override 200 | public final synchronized long getSequenceNumber(){ 201 | checkIfRecycled(); 202 | return sequenceNumber; 203 | } 204 | 205 | @Override 206 | public final synchronized long getCaptureTime(){ 207 | checkIfRecycled(); 208 | return captureTime; 209 | } 210 | 211 | @Override 212 | public final synchronized void recycle() { 213 | if (! recycled){ 214 | frameGrabber.recycleVideoBuffer(this); 215 | recycled = true; 216 | notifyAll(); 217 | } 218 | } 219 | } 220 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/VideoFrame.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Gilles Gigan (gilles.gigan@gmail.com) 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by the 6 | * Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 11 | * or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | package au.edu.jcu.v4l4j; 19 | 20 | import java.awt.image.BufferedImage; 21 | import java.awt.image.DataBuffer; 22 | import java.awt.image.Raster; 23 | 24 | import au.edu.jcu.v4l4j.exceptions.StateException; 25 | import au.edu.jcu.v4l4j.exceptions.UnsupportedMethod; 26 | 27 | /** 28 | * Objects implementing this interface represent a single video frame captured by v4l4j. 29 | * They provide access to image data through various objects, including byte arrays 30 | * and {@link DataBuffer}s. During capture, v4l4j creates VideoFrames 31 | * and passes them the registered {@link CaptureCallback} object. Check the 32 | * {@link FrameGrabber} class for more information on how to perform a capture.
33 | * When accessing the image data as a byte array, as returned by {@link #getBytes()}, 34 | * note that the size of returned byte array can be longer than the actual image size. 35 | * What this means is that you should use {@link #getFrameLength()} to figure out how 36 | * many elements in the byte array are actually used by the image instead of relying 37 | * on byte[].length.
38 | * From the moment a VideoFrame is returned by a frame grabber, the 39 | * VideoFrame object itself as well as any of the objects obtained through 40 | * its methods can be used. When the VideoFrame and any of the objects 41 | * obtained through it) are dealt with and no longer used, the VideoFrame 42 | * must be recycled, which marks it as being available to v4l4j to store an upcoming 43 | * image. From the moment a VideoFrame is recycled, 44 | * neither the VideoFrame nor objects obtained through it 45 | * can be used. Bad things will happen if you violate this rule. It is recommended 46 | * that you explicitly set all references to this object, as well as references to objects 47 | * obtained through this frame, to null.
48 | * Note that not all video frames are capable of returning a raster or a buffered image. 49 | * For example, rasters cannot be created for compressed image formats, 50 | * which means VideoFrames returned by {@link JPEGFrameGrabber}s 51 | * cannot return a buffered image, and calling {@link #getBufferedImage()} will 52 | * throw a {@link UnsupportedMethod} exception. In the same way, video frames 53 | * returned by raw frame grabbers cannot create rasters and an {@link UnsupportedMethod} 54 | * exception will be thrown if {@link #getRaster()} is called. 55 | * @author gilles 56 | * 57 | */ 58 | public interface VideoFrame { 59 | /** 60 | * This method returns the frame grabber object which captured this frame 61 | * @return the frame grabber object which captured this frame. 62 | */ 63 | public FrameGrabber getFrameGrabber(); 64 | 65 | /** 66 | * This method returns the length of this video frame in bytes. 67 | * @return the length of this video frame in bytes. 68 | * @throws StateException if this video frame has been recycled already. 69 | */ 70 | public int getFrameLength(); 71 | 72 | /** 73 | * This method returns this video frame's sequence number (a monotonically 74 | * increasing number for each captured frame). This number can be used 75 | * to find out when a frame was dropped: if currentSequenceNumber != 76 | * (previousSequenceNumber + 1) then (currentSequenceNumber - 77 | * previousSequenceNumber( frames were dropped. 78 | * @return this video frame's sequence number 79 | * @throws StateException if this video frame has been recycled already. 80 | */ 81 | public long getSequenceNumber(); 82 | 83 | /** 84 | * This method returns the OS time (number of microseconds elapsed since 85 | * startup) at which this video frame was captured. 86 | * @return the OS time (number of microseconds elapsed since 87 | * startup) at which this video frame was captured. 88 | * @throws StateException if this video frame has been recycled already. 89 | */ 90 | public long getCaptureTime(); 91 | 92 | /** 93 | * This method returns the image data as a byte array.Please note that 94 | * the size of the returned byte array can be greater than the actual frame 95 | * size. You should not use the byte array length (as returned by 96 | * byte[].length) as the length of the image. Instead, use the 97 | * value returned from {@link #getFrameLength()}. 98 | * @return the image data as a byte array. The array may be longer than 99 | * the actual frame length. 100 | * @throws StateException if this video frame has been recycled already. 101 | */ 102 | public byte[] getBytes(); 103 | 104 | /** 105 | * This method returns the image data encapsulated in a {@link DataBuffer} 106 | * object. The data is stored as bytes in the data buffer. 107 | * @return the image data encapsulated in a {@link DataBuffer} 108 | * @throws StateException if this video frame has been recycled already. 109 | */ 110 | public DataBuffer getDataBuffer(); 111 | 112 | /** 113 | * This method returns the image data encapsulated in a {@link Raster} object. 114 | * Rasters cannot be created for some image formats (including compressed formats 115 | * like JPEG). In this case this method will throw a {@link UnsupportedMethod} 116 | * exception. 117 | * @return the image data encapsulated in a {@link Raster} object 118 | * @throws {@link UnsupportedMethod} exception if the image format this 119 | * video frame uses cannot be encapsulated in a {@link Raster}. 120 | * @throws StateException if this video frame has been recycled already. 121 | */ 122 | public Raster getRaster(); 123 | 124 | /** 125 | * This method returns the image data encapsulated in a {@link BufferedImage} object. 126 | * Buffered images cannot be created for some image formats (including raw image 127 | * formats). In this case this method will throw a {@link UnsupportedMethod} 128 | * exception. 129 | * @return the image data encapsulated in a {@link BufferedImage} object 130 | * @throws {@link UnsupportedMethod} exception if the image format this 131 | * video frame uses cannot be encapsulated in a {@link BufferedImage}. 132 | * @throws StateException if this video frame has been recycled already. 133 | */ 134 | public BufferedImage getBufferedImage(); 135 | 136 | /** 137 | * This method marks this video frame as being no longer used, and ready 138 | * to be reused by v4l4j. After calling this method, do not use either 139 | * this object or any of the objects obtained through it 140 | * (byte array, data buffer, raster, buffered image, ...) or bad things 141 | * WILL happen. 142 | */ 143 | public void recycle(); 144 | } 145 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/JPEGFrameGrabber.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2008 Gilles Gigan (gilles.gigan@gmail.com) 3 | * eResearch Centre, James Cook University (eresearch.jcu.edu.au) 4 | * 5 | * This program was developed as part of the ARCHER project 6 | * (Australian Research Enabling Environment) funded by a 7 | * Systemic Infrastructure Initiative (SII) grant and supported by the Australian 8 | * Department of Innovation, Industry, Science and Research 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17 | * or FITNESS FOR A PARTICULAR PURPOSE. 18 | * See the GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | * 23 | */ 24 | package au.edu.jcu.v4l4j; 25 | 26 | import java.util.concurrent.ThreadFactory; 27 | 28 | import au.edu.jcu.v4l4j.exceptions.CaptureChannelException; 29 | import au.edu.jcu.v4l4j.exceptions.ImageFormatException; 30 | import au.edu.jcu.v4l4j.exceptions.InitialisationException; 31 | import au.edu.jcu.v4l4j.exceptions.StateException; 32 | import au.edu.jcu.v4l4j.exceptions.V4L4JException; 33 | import au.edu.jcu.v4l4j.exceptions.VideoStandardException; 34 | 35 | 36 | /** 37 | * Objects of this class are used to retrieve JPEG-encoded frames from a 38 | * {@link VideoDevice}. A JPEG frame grabber can only be created 39 | * if the associated video device can produce images in a format v4l4j 40 | * knows how to encode in JPEG. The {@link VideoDevice#supportJPEGConversion()} 41 | * method can be used to find out whether a video device can have its images 42 | * JPEG-encoded by v4l4j, ie if a JPEG frame grabber can be instantiated. 43 | * JPEGFrameGrabber objects are not 44 | * instantiated directly. Instead, the 45 | * {@link VideoDevice#getJPEGFrameGrabber(int, int, int, int, int)} 46 | * or 47 | * {@link VideoDevice#getJPEGFrameGrabber(int, int, int, int, int, ImageFormat)} 48 | * method must be called on the associated {@link VideoDevice}. JPEG frame grabbers 49 | * implement the {@link FrameGrabber} interface which provides methods to handle 50 | * video capture. See {@link FrameGrabber its documentation} for more information. 51 | * 52 | * @see FrameGrabber {@link FrameGrabber} 53 | * @author gilles 54 | * 55 | */ 56 | public class JPEGFrameGrabber extends AbstractGrabber { 57 | 58 | private int quality; 59 | 60 | /** 61 | * This constructor builds a FrameGrabber object used to capture JPEG frames 62 | * from a video source 63 | * @param di the DeviceInfo of the VideoDevice who created this frame grabber 64 | * @param w the requested frame width 65 | * @param h the requested frame height 66 | * @param ch the input index, as returned by {@link InputInfo#getIndex()} 67 | * @param std the video standard, as returned by 68 | * {@link InputInfo#getSupportedStandards()} (see V4L4JConstants). 69 | * @param q the JPEG image quality (the higher, the better the quality), 70 | * between the range {@link V4L4JConstants#MIN_JPEG_QUALITY} and 71 | * {@link V4L4JConstants#MAX_JPEG_QUALITY}. 72 | * @param imf the image format frame should be captured in 73 | * @param factory the thread factory to use when creating the push source 74 | */ 75 | JPEGFrameGrabber(DeviceInfo di,long o, int w, int h, int ch, int std, int q 76 | , Tuner t,ImageFormat imf, ThreadFactory factory) throws V4L4JException{ 77 | super(di, o,w,h,ch,std, t , imf, JPEG_GRABBER, factory); 78 | quality = q; 79 | } 80 | 81 | /** 82 | * This method initialises the capture, and apply the capture parameters. 83 | * V4L may either adjust the height and width parameters to the closest 84 | * valid values or reject them altogether. If the values were adjusted, they 85 | * can be retrieved after calling {@link #init()} using {@link #getWidth()} 86 | * and {@link #getHeight()} 87 | * @throws VideoStandardException if the chosen video standard is not 88 | * supported 89 | * @throws ImageFormatException this exception is thrown if the chosen image 90 | * format cannot be JPEG encoded. If no image format was chosen, the video 91 | * device does not have any image formats that can be jpeg encoded 92 | * (let the author know, see README file) 93 | * @throws CaptureChannelException if the given channel number value is not 94 | * valid 95 | * @throws ImageDimensionException if the given image dimensions are not 96 | * supported 97 | * @throws InitialisationException if the video device file can not be 98 | * initialised 99 | * @throws StateException if the frame grabber is already initialised 100 | * or released 101 | * @throws V4L4JException if there is an error applying capture parameters 102 | */ 103 | void init() throws V4L4JException{ 104 | try { 105 | super.init(); 106 | setJPGQuality(quality); 107 | } catch (ImageFormatException ife){ 108 | if(format == -1){ 109 | String msg ="v4l4j was unable to find image format supported by" 110 | + "the \nvideo device and that can be encoded in JPEG.\n" 111 | + "Please let the author know about this, so that support\n" 112 | + "for this video device can be improved. See \nREADME file" 113 | + " on how to submit v4l4j reports."; 114 | System.out.println(msg); 115 | ife = new ImageFormatException(msg); 116 | } 117 | 118 | throw ife; 119 | } 120 | } 121 | 122 | /** 123 | * This method sets the desired JPEG quality. 124 | * @param q the quality (between 125 | * {@link V4L4JConstants#MIN_JPEG_QUALITY} and 126 | * {@link V4L4JConstants#MAX_JPEG_QUALITY} inclusive) 127 | * @throws StateException if this 128 | * FrameGrabber has been already released, and therefore must 129 | * not be used anymore. 130 | */ 131 | public void setJPGQuality(int q){ 132 | state.checkReleased(); 133 | if(qV4L4JConstants.MAX_JPEG_QUALITY) 136 | q = V4L4JConstants.MAX_JPEG_QUALITY; 137 | 138 | setQuality(object, q); 139 | quality = q; 140 | } 141 | 142 | /** 143 | * This method returns the current JPEG quality. 144 | * @return the JPEG quality 145 | * @throws StateException if this 146 | * FrameGrabber has been already released, and therefore must 147 | * not be used anymore. 148 | */ 149 | public int getJPGQuality(){ 150 | state.checkReleased(); 151 | return quality; 152 | } 153 | 154 | /** 155 | * This method returns the native image format used by this 156 | * FrameGrabber. The returned format specifies the image format the capture 157 | * uses, ie the one images are retrieved from the device BEFORE JPEG 158 | * conversion. 159 | * @return the native image format used by this FrameGrabber. 160 | * @throws StateException if this 161 | * FrameGrabber has been already released, and therefore must 162 | * not be used anymore. 163 | */ 164 | public ImageFormat getImageFormat(){ 165 | state.checkReleased(); 166 | return dInfo.getFormatList().getNativeFormat(format); 167 | } 168 | 169 | @Override 170 | protected void createBuffers(int bufferSize) { 171 | int numberOfBuffers = nbV4LBuffers; 172 | while(numberOfBuffers-- > 0) 173 | videoFrames.add(new JPEGVideoFrame(this, bufferSize)); 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /svn.log: -------------------------------------------------------------------------------- 1 | A v4l4j-trunk/lib 2 | A v4l4j-trunk/lib/junit-4.1.jar 3 | A v4l4j-trunk/TestedHardware 4 | A v4l4j-trunk/Changelog 5 | A v4l4j-trunk/src 6 | A v4l4j-trunk/src/v4l4j_DeviceInfo.c 7 | A v4l4j-trunk/src/v4l4j_ResolutionInfo.c 8 | A v4l4j-trunk/src/v4l4j_FrameGrabber.c 9 | A v4l4j-trunk/src/v4l4j_Control.c 10 | A v4l4j-trunk/src/v4l4j_VideoDevice.c 11 | A v4l4j-trunk/src/v4l4j_ImageFormatList.c 12 | A v4l4j-trunk/src/rgb.h 13 | A v4l4j-trunk/src/pixfmt-conv.h 14 | A v4l4j-trunk/src/v4l4j_Tuner.c 15 | A v4l4j-trunk/src/v4l4j_FrameInterval.c 16 | A v4l4j-trunk/src/au 17 | A v4l4j-trunk/src/au/edu 18 | A v4l4j-trunk/src/au/edu/jcu 19 | A v4l4j-trunk/src/au/edu/jcu/v4l4j 20 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/PushSource.java 21 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/TunerInfo.java 22 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/UncompressedVideoFrame.java 23 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/ControlList.java 24 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/FrameGrabber.java 25 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/Control.java 26 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/YVUFrameGrabber.java 27 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/package-info.java 28 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/JPEGFrameGrabber.java 29 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/VideoDevice.java 30 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/V4L4JDataBuffer.java 31 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/AbstractGrabber.java 32 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/RawFrameGrabber.java 33 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/TunerList.java 34 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/Tuner.java 35 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/FrameInterval.java 36 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/test 37 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/test/FrameGrabberTest.java 38 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/test/PushSourceTest.java 39 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/test/MemLeak.java 40 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/V4L4JConstants.java 41 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/exceptions 42 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/exceptions/InitialisationException.java 43 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/exceptions/ReleaseException.java 44 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/exceptions/StateException.java 45 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/exceptions/JNIException.java 46 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/exceptions/ControlException.java 47 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/exceptions/V4L4JException.java 48 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/exceptions/InvalidValue.java 49 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/exceptions/package-info.java 50 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/exceptions/VideoStandardException.java 51 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/exceptions/NoTunerException.java 52 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/exceptions/UnsupportedMethod.java 53 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/exceptions/ImageDimensionsException.java 54 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/exceptions/ImageFormatException.java 55 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/exceptions/CaptureChannelException.java 56 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/BGRFrameGrabber.java 57 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/RGBFrameGrabber.java 58 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/InputInfo.java 59 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/DeviceInfo.java 60 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/BaseVideoFrame.java 61 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/ResolutionInfo.java 62 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/CaptureCallback.java 63 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/VideoFrame.java 64 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/YUVFrameGrabber.java 65 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/V4L4JRaster.java 66 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/JPEGVideoFrame.java 67 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/ImageFormatList.java 68 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/ImageFormat.java 69 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/examples 70 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/examples/GetSnapshotApp.java 71 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/examples/DumpInfo.java 72 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/examples/package-info.java 73 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/examples/server 74 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/examples/server/CamServer.java 75 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/examples/server/ClientConnection.java 76 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/examples/GetFrameRate.java 77 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/examples/DualViewer.java 78 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/examples/videoViewer 79 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/examples/videoViewer/DeviceChooser.java 80 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/examples/videoViewer/ControlViewer.java 81 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/examples/videoViewer/JPEGViewer.java 82 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/examples/videoViewer/RGBViewer.java 83 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/examples/videoViewer/AbstractVideoViewer.java 84 | A v4l4j-trunk/src/au/edu/jcu/v4l4j/examples/SimpleViewer.java 85 | A v4l4j-trunk/src/jpeg.c 86 | A v4l4j-trunk/src/jpeg.h 87 | A v4l4j-trunk/src/debug.h 88 | A v4l4j-trunk/src/Makefile 89 | A v4l4j-trunk/src/common.h 90 | A v4l4j-trunk/COPYING 91 | A v4l4j-trunk/resources 92 | A v4l4j-trunk/resources/v4l4j-48x48.png 93 | A v4l4j-trunk/resources/v4l4j.png 94 | A v4l4j-trunk/build.properties 95 | A v4l4j-trunk/CREDITS 96 | A v4l4j-trunk/README 97 | A v4l4j-trunk/libvideo 98 | A v4l4j-trunk/libvideo/v4l1-query.h 99 | A v4l4j-trunk/libvideo/v4l2-query.h 100 | A v4l4j-trunk/libvideo/gspca-probe.c 101 | A v4l4j-trunk/libvideo/dump-capture.c 102 | A v4l4j-trunk/libvideo/Changelog 103 | A v4l4j-trunk/libvideo/pwc-ioctl.h 104 | A v4l4j-trunk/libvideo/gspca-probe.h 105 | A v4l4j-trunk/libvideo/example 106 | A v4l4j-trunk/libvideo/example/main.c 107 | A v4l4j-trunk/libvideo/example/utils.h 108 | A v4l4j-trunk/libvideo/example/jpeg.c 109 | A v4l4j-trunk/libvideo/example/log.h 110 | A v4l4j-trunk/libvideo/example/jpeg.h 111 | A v4l4j-trunk/libvideo/example/README 112 | A v4l4j-trunk/libvideo/example/Makefile 113 | A v4l4j-trunk/libvideo/test-capture.c 114 | A v4l4j-trunk/libvideo/libvideo-palettes.h 115 | A v4l4j-trunk/libvideo/palettes.c 116 | A v4l4j-trunk/libvideo/v4l1-tuner.c 117 | A v4l4j-trunk/libvideo/v4l2-tuner.c 118 | A v4l4j-trunk/libvideo/v4l1-tuner.h 119 | A v4l4j-trunk/libvideo/v4l2-tuner.h 120 | A v4l4j-trunk/libvideo/COPYING 121 | A v4l4j-trunk/libvideo/fps-param-probe.c 122 | A v4l4j-trunk/libvideo/videodev2.h 123 | A v4l4j-trunk/libvideo/Makefile 124 | A v4l4j-trunk/libvideo/libvideo.c 125 | A v4l4j-trunk/libvideo/pwc-probe.c 126 | A v4l4j-trunk/libvideo/list-caps.c 127 | A v4l4j-trunk/libvideo/fps-param-probe.h 128 | A v4l4j-trunk/libvideo/libvideo.h 129 | A v4l4j-trunk/libvideo/quickcam.h 130 | A v4l4j-trunk/libvideo/pwc-probe.h 131 | A v4l4j-trunk/libvideo/qc-probe.c 132 | A v4l4j-trunk/libvideo/videodev_additions.h 133 | A v4l4j-trunk/libvideo/videodev.h 134 | A v4l4j-trunk/libvideo/README 135 | A v4l4j-trunk/libvideo/qc-probe.h 136 | A v4l4j-trunk/libvideo/linux 137 | A v4l4j-trunk/libvideo/linux/compiler.h 138 | A v4l4j-trunk/libvideo/linux/v4l2-common.h 139 | A v4l4j-trunk/libvideo/linux/compiler-intel.h 140 | A v4l4j-trunk/libvideo/linux/compiler-gcc.h 141 | A v4l4j-trunk/libvideo/linux/compiler-gcc3.h 142 | A v4l4j-trunk/libvideo/linux/compiler-gcc4.h 143 | A v4l4j-trunk/libvideo/svn-version.sh 144 | A v4l4j-trunk/libvideo/v4l1-input.c 145 | A v4l4j-trunk/libvideo/v4l2-input.c 146 | A v4l4j-trunk/libvideo/TODO 147 | A v4l4j-trunk/libvideo/TestedHardware 148 | A v4l4j-trunk/libvideo/log.h 149 | A v4l4j-trunk/libvideo/v4l1-input.h 150 | A v4l4j-trunk/libvideo/libvideo-err.h 151 | A v4l4j-trunk/libvideo/v4l2-input.h 152 | A v4l4j-trunk/libvideo/v4l1-query.c 153 | A v4l4j-trunk/libvideo/v4l2-query.c 154 | A v4l4j-trunk/build.xml 155 | U v4l4j-trunk 156 | Checked out revision 507. 157 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/DeviceInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2008 Gilles Gigan (gilles.gigan@gmail.com) 3 | * eResearch Centre, James Cook University (eresearch.jcu.edu.au) 4 | * 5 | * This program was developed as part of the ARCHER project 6 | * (Australian Research Enabling Environment) funded by a 7 | * Systemic Infrastructure Initiative (SII) grant and supported by the Australian 8 | * Department of Innovation, Industry, Science and Research 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17 | * or FITNESS FOR A PARTICULAR PURPOSE. 18 | * See the GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | * 23 | */ 24 | package au.edu.jcu.v4l4j; 25 | 26 | import java.util.List; 27 | import java.util.Vector; 28 | 29 | import au.edu.jcu.v4l4j.exceptions.StateException; 30 | import au.edu.jcu.v4l4j.exceptions.V4L4JException; 31 | 32 | /** 33 | * Objects of this class encapsulate the following information about a video 34 | * device: 35 | *
    36 | *
  • its device file,
  • 37 | *
  • the name of the video device,
  • 38 | *
  • a list of {@link InputInfo} objects providing information about each 39 | * video input,
  • 40 | *
  • a list of {@link ImageFormat}s, capture resolutions 41 | * ({@link ResolutionInfo}) and frame intervals supported by the video device. 42 | *
43 | * To retrieve information about a video device, call 44 | * {@link VideoDevice#getDeviceInfo()} on its 45 | * VideoDevice object, and retrieve parameters of interest. 46 | * Example:
47 | * 48 | * VideoDevice vd = new VideoDevice("/dev/video0");
49 | * DeviceInfo d = vd.getDeviceInfo();
50 | * System.out.println("name: "+d.getName());
51 | * System.out.println("Device file: "+d.getDeviceFile());
52 | * System.out.println("Supported formats:");
53 | * for(ImageFormat f : d.getFormatList().getNativeFormats())
54 | *   System.out.println("\t"+f.toNiceString());
55 | * System.out.println("\tFormats that can be RGB24-converted: " 56 | * +(vd.supportRGBConversion()?"":"None"));
57 | * if(vd.supportRGBConversion())
58 | *   for(ImageFormat f: d.getFormatList().getRGBEncodableFormats())
59 | *     System.out.println("\t\t"+f.toNiceString());
60 | * System.out.println("Inputs:");
61 | * for(InputInfo i: d.getInputs()){
62 | *   System.out.println("\tName: "+i.getName());
63 | *   System.out.println("\tType: "+i.getType()+"("+ 64 | * (i.getType() == V4L4JConstants.CAMERA ? "Camera" : "Tuner")+")");
65 | *   System.out.println("\tIndex: "+i.getIndex());
66 | *   System.out.println("\tSupported standards:");
67 | *   for(Integer s: i.getSupportedStandards()){
68 | *     System.out.print("\t\t"+s);
69 | *     if(s==V4L4JConstants.PAL)
70 | *       System.out.println("(PAL)");
71 | *     else if(s==V4L4JConstants.NTSC)
72 | *       System.out.println("(NTSC)");
73 | *     else if(s==V4L4JConstants.SECAM)
74 | *       System.out.println("(SECAM)");
75 | *     else
77 | *   }
78 | *   if(i.getType() == V4L4JConstants.TUNER) {
79 | *     TunerInfo t = i.getTuner();
80 | *     System.out.println("\tTuner");
81 | *     System.out.println("\t\tname: "+t.getName());
82 | *     System.out.println("\t\tIndex: "+t.getIndex());
83 | *     System.out.println("\t\tRange high: "+ 84 | * t.getRangeHigh());
85 | *     System.out.println("\t\tRange low: "+ 86 | * t.getRangeLow());
87 | *     System.out.println("\t\tUnit: "+ 88 | * t.getUnit()+"("+(t.getUnit() == TunerInfo.MHZ ? "MHz" : "kHz")+")");
89 | *     System.out.println("\t\tType: "+ 90 | * t.getType()+"("+(t.getType() == TunerInfo.RADIO ? "Radio" : "TV")+")");
91 | *   }
92 | * }
93 | * vd.release();
94 | *
95 | *
96 | * {@link DeviceInfo} objects can not be used anymore once the matching 97 | * VideoDevice object has been released. Calling any methods will then throw 98 | * a {@link StateException}. 99 | * 100 | * @author gilles 101 | * 102 | */ 103 | public class DeviceInfo { 104 | /** 105 | * Native method interacting with libvideo to get info on device f 106 | * @param f the full path to the V4L device file 107 | */ 108 | private native void getInfo(long o); 109 | 110 | /** 111 | * this method releases the libvideo query interface 112 | * @param o a pointer to a v4l4j_Device struct 113 | */ 114 | private native void doRelease(long o); 115 | 116 | /** 117 | * this method returns a frame interval object representing the supported 118 | * frame intervals for capture at the given resolution using the given 119 | * format 120 | * @param o a JNI pointer to a struct v4l4j_device 121 | * @param imf the libvideo image format 122 | * @param w the capture width 123 | * @param h the capture height 124 | * @return a frame interval object 125 | */ 126 | private native FrameInterval doListIntervals(long o, int imf, int w, int h); 127 | 128 | 129 | static { 130 | try { 131 | System.loadLibrary("v4l4j"); 132 | } catch (UnsatisfiedLinkError e) { 133 | System.err.println("Cant load v4l4j JNI library"); 134 | throw e; 135 | } 136 | } 137 | 138 | /** 139 | * The name of the video device 140 | */ 141 | private String name; 142 | 143 | /** 144 | * The path to the device file 145 | */ 146 | private String deviceFile; 147 | 148 | /** 149 | * A list of inputs connected to this device 150 | */ 151 | private List inputs; 152 | 153 | /** 154 | * A list of supported image formats 155 | */ 156 | private ImageFormatList formats; 157 | 158 | /** 159 | * a pointer to a C struct v4l4j_device 160 | */ 161 | private long object; 162 | 163 | /** 164 | * whether the device info has been released 165 | */ 166 | private boolean released; 167 | 168 | 169 | /** 170 | * This method returns the name of the video device. 171 | * @return the name of the video device. 172 | * @throws StateException if the associated VideoDevice has been released 173 | */ 174 | public synchronized String getName() { 175 | checkRelease(); 176 | return name; 177 | } 178 | 179 | /** 180 | * This method returns the device file associated with the video device. 181 | * @return the device file 182 | * @throws StateException if the associated VideoDevice has been released 183 | */ 184 | public synchronized String getDeviceFile() { 185 | checkRelease(); 186 | return deviceFile; 187 | } 188 | 189 | 190 | /** 191 | * This method returns a list of {@link InputInfo} objects which provide 192 | * information about each video input supported by the video device. 193 | * @return a list of InputInfo objects 194 | * @throws StateException if the associated VideoDevice has been released 195 | * @see InputInfo 196 | */ 197 | public synchronized List getInputs() { 198 | checkRelease(); 199 | return new Vector(inputs); 200 | } 201 | 202 | 203 | /** 204 | * This method returns an {@link ImageFormatList} object containing 205 | * the various image formats, capture resolutions and frame intervals the 206 | * video device supports. 207 | * @return anImageFormatList object 208 | * @throws StateException if the associated VideoDevice has been released 209 | * @see ImageFormatList 210 | */ 211 | public synchronized ImageFormatList getFormatList() { 212 | checkRelease(); 213 | return formats; 214 | } 215 | 216 | 217 | /** 218 | * This method returns a {@link FrameInterval} object containing information 219 | * about the supported frame intervals for capture at the given resolution 220 | * and image format. Note that the returned {@link FrameInterval} object 221 | * could have its type set to {@link FrameInterval.Type#UNSUPPORTED} if the 222 | * driver does not support frame interval enumeration OR if the device is 223 | * currently being used by another application and frame intervals cannot 224 | * be enumerated at this time.
Frame interval information can also 225 | * be obtained through {@link ResolutionInfo} objects, attached to each 226 | * {@link ImageFormat}. See {@link #getFormatList()}. 227 | * @return a {@link FrameInterval} object containing information about 228 | * the supported frame intervals 229 | * @param imf the capture image format for which the frame intervals should 230 | * be enumerated 231 | * @param width the capture width for which the frame intervals should be 232 | * enumerated 233 | * @param height the capture height for which the frame intervals should be 234 | * enumerated 235 | * @throws StateException if the associated VideoDevice has been released 236 | */ 237 | public synchronized FrameInterval listIntervals(ImageFormat imf, 238 | int width, int height){ 239 | checkRelease(); 240 | return doListIntervals(object, imf.getIndex(), width, height); 241 | } 242 | 243 | 244 | /** 245 | * This constructor build a DeviceInfo object containing information about 246 | * the given V4L device. 247 | * @param object the JNI C pointer to struct v4l4j_device 248 | * @throws V4L4JException if there is an error retrieving information from 249 | * the video device. 250 | */ 251 | DeviceInfo(long object, String dev) throws V4L4JException{ 252 | inputs = new Vector(); 253 | deviceFile = dev; 254 | getInfo(object); 255 | this.object = object; 256 | } 257 | 258 | /** 259 | * This method releases the libvideo query interface 260 | */ 261 | synchronized void release() { 262 | doRelease(object); 263 | } 264 | 265 | /** 266 | * checks if this object has been released (by the owning video device 267 | * object). If yes, throws a {@link StateException} 268 | * @throws StateException if this object has been released 269 | */ 270 | private void checkRelease() throws StateException{ 271 | if(released) 272 | throw new StateException("The video device object has been released"); 273 | } 274 | 275 | /* (non-Javadoc) 276 | * @see java.lang.Object#hashCode() 277 | */ 278 | @Override 279 | public int hashCode() { 280 | final int prime = 31; 281 | int result = 1; 282 | result = prime * result 283 | + ((deviceFile == null) ? 0 : deviceFile.hashCode()); 284 | return result; 285 | } 286 | 287 | /* (non-Javadoc) 288 | * @see java.lang.Object#equals(java.lang.Object) 289 | */ 290 | @Override 291 | public boolean equals(Object obj) { 292 | if (this == obj) { 293 | return true; 294 | } 295 | if (obj == null) { 296 | return false; 297 | } 298 | if (!(obj instanceof DeviceInfo)) { 299 | return false; 300 | } 301 | DeviceInfo other = (DeviceInfo) obj; 302 | if (deviceFile == null) { 303 | if (other.deviceFile != null) { 304 | return false; 305 | } 306 | } else if (!deviceFile.equals(other.deviceFile)) { 307 | return false; 308 | } 309 | return true; 310 | } 311 | } 312 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/V4L4JConstants.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2008 Gilles Gigan (gilles.gigan@gmail.com) 3 | * eResearch Centre, James Cook University (eresearch.jcu.edu.au) 4 | * 5 | * This program was developed as part of the ARCHER project 6 | * (Australian Research Enabling Environment) funded by a 7 | * Systemic Infrastructure Initiative (SII) grant and supported by the Australian 8 | * Department of Innovation, Industry, Science and Research 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17 | * or FITNESS FOR A PARTICULAR PURPOSE. 18 | * See the GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | * 23 | */ 24 | 25 | package au.edu.jcu.v4l4j; 26 | 27 | public class V4L4JConstants { 28 | 29 | /** 30 | * Input from a tuner 31 | */ 32 | public static final short INPUT_TYPE_TUNER = 1; 33 | /** 34 | * Camera-type input 35 | */ 36 | public static final short INPUT_TYPE_CAMERA = 2; 37 | /** 38 | * Video standard value for webcams 39 | */ 40 | public static final int STANDARD_WEBCAM=0; 41 | /** 42 | * Video standard value for PAL sources 43 | */ 44 | public static final int STANDARD_PAL=1; 45 | /** 46 | * Video standard value for SECAM sources 47 | */ 48 | public static final int STANDARD_SECAM=2; 49 | /** 50 | * Video standard value for NTSC sources 51 | */ 52 | public static final int STANDARD_NTSC=3; 53 | /** 54 | * Setting the capture width to this value will set the actual width to the 55 | * maximum width supported by the hardware 56 | */ 57 | public static final int MAX_WIDTH = 0; 58 | /** 59 | * Setting the capture height to this value will set the actual height to 60 | * the maximum height supported by the hardware 61 | */ 62 | public static final int MAX_HEIGHT = 0; 63 | /** 64 | * This value represents the maximum value of the JPEG quality setting 65 | */ 66 | public static final int MAX_JPEG_QUALITY = 100; 67 | /** 68 | * This value represents the minimum value of the JPEG quality setting 69 | */ 70 | public static final int MIN_JPEG_QUALITY = 0; 71 | /** 72 | * If a control has a type equal to CTRL_TYPE_BUTTON, its value is always 0, 73 | * and pressing it is done by setting any value using 74 | * {@link Control#setValue(int)}. 75 | */ 76 | public final static int CTRL_TYPE_BUTTON=0; 77 | /** 78 | * If a control has a type equal to CTRL_TYPE_SLIDER, it accepts a range of 79 | * values between a minimum (as returned by {@link Control#getMinValue()}) 80 | * and a maximum (as returned by {@link Control#getMaxValue()}) in 81 | * increments (as returned by {@link Control#getStepValue()}) 82 | */ 83 | public final static int CTRL_TYPE_SLIDER=1; 84 | /** 85 | * If a control has a type equal to CTRL_TYPE_SWITCH, it accepts two 86 | * different values: 87 | * 0 (as returned by {@link Control#getMinValue()}) and 88 | * 1 (as returned by {@link Control#getMaxValue()}. 89 | */ 90 | public final static int CTRL_TYPE_SWITCH=2; 91 | /** 92 | * If a control has a type equal to CTRL_TYPE_DISCRETE, it only accepts 93 | * a set of values (discrete values). This set of acceptable values is 94 | * returned by {@link Control#getDiscreteValues()}. 95 | * These discrete values may have string descriptions (returned by 96 | * {@link Control#getDiscreteValueNames()}) and are in the range 97 | * {@link Control#getMinValue()} and {@link Control#getMaxValue()}. The 98 | * step value as returned by {@link Control#getStepValue()} is not 99 | * applicable. 100 | */ 101 | public final static int CTRL_TYPE_DISCRETE=3; 102 | /** 103 | * If a control has a type equal to CTRL_TYPE_STRING, it only accepts / 104 | * returns strings. 105 | * {@link Control#getMinValue()} and {@link Control#getMaxValue()} return 106 | * the minimum and maximum string length. The actual value is set / retrieved 107 | * with {@link Control#setStringValue(String)} and {@link Control#getStringValue()}. 108 | */ 109 | public final static int CTRL_TYPE_STRING=4; 110 | /** 111 | * If a control has a type equal to CTRL_TYPE_LONG, it only accepts long values, 112 | * between {@link Long#MIN_VALUE} and {@link Long#MAX_VALUE} with a step value 113 | * of 1. The actual value is set / retrieved 114 | * with {@link Control#setLongValue(long)} and {@link Control#getLongValue()}. 115 | */ 116 | public final static int CTRL_TYPE_LONG=5; 117 | /** 118 | * If a control has a type equal to CTRL_TYPE_BITMASK, it only accepts integer values, 119 | * between 0 and {@link Integer#MAX_VALUE} with a step value 120 | * of 1. The actual value is set / retrieved 121 | * with {@link Control#setValue(int)} and {@link Control#getValue()}. 122 | */ 123 | public final static int CTRL_TYPE_BITMASK=6; 124 | 125 | 126 | /** 127 | * A tuner with a type (as returned by {@link TunerInfo#getType()}) equal to 128 | * TUNER_TYPE_RADIO is a radio tuner 129 | */ 130 | public static final int TUNER_TYPE_RADIO = 1; 131 | /** 132 | * A tuner with a type (as returned by {@link TunerInfo#getType()}) equal to 133 | * TUNER_TV_TYPE is a TV tuner 134 | */ 135 | public static final int TUNER_TYPE_TV = 2; 136 | /** 137 | * Frequencies of a tuner (as returned by 138 | * {@link TunerInfo#getUnit()}) are expressed in KHz 139 | */ 140 | public static final int FREQ_KHZ = 1; 141 | /** 142 | * Frequencies of a tuner (as returned by 143 | * {@link TunerInfo#getUnit()}) are expressed in MHz 144 | */ 145 | public static final int FREQ_MHZ = 2; 146 | 147 | // RGB image formats 148 | /** 149 | * RGB332 image format 150 | */ 151 | public static final int IMF_RGB332=0; 152 | /** 153 | * RGB444 image format 154 | */ 155 | public static final int IMF_RGB444=1; 156 | /** 157 | * RGB555 image format 158 | */ 159 | public static final int IMF_RGB555=2; 160 | /** 161 | * RGB565 image format 162 | */ 163 | public static final int IMF_RGB565=3; 164 | /** 165 | * RGB555X image format 166 | */ 167 | public static final int IMF_RGB555X=4; 168 | /** 169 | * RGB565X image format 170 | */ 171 | public static final int IMF_RGB565X=5; 172 | /** 173 | * BGR24 image format 174 | */ 175 | public static final int IMF_BGR24=6; 176 | /** 177 | * RGB24 image format 178 | */ 179 | public static final int IMF_RGB24=7; 180 | /** 181 | * BGR32 image format 182 | */ 183 | public static final int IMF_BGR32=8; 184 | /** 185 | * RGB32 image format 186 | */ 187 | public static final int IMF_RGB32=9; 188 | 189 | // Grey image formats 190 | /** 191 | * GREY image format 192 | */ 193 | public static final int IMF_GREY=10; 194 | /** 195 | * Y4 image format 196 | */ 197 | public static final int IMF_Y4=11; 198 | /** 199 | * Y6 image format 200 | */ 201 | public static final int IMF_Y6=12; 202 | /** 203 | * Y10 image format 204 | */ 205 | public static final int IMF_Y10=13; 206 | /** 207 | * Y16 image format 208 | */ 209 | public static final int IMF_Y16=14; 210 | 211 | // PAL 8 format 212 | /** 213 | * PAL8 image format 214 | */ 215 | public static final int IMF_PAL8=15; 216 | 217 | // YUV formats 218 | /** 219 | * YVU410 image format 220 | */ 221 | public static final int IMF_YVU410=16; 222 | /** 223 | * YVU420 image format 224 | */ 225 | public static final int IMF_YVU420=17; 226 | /** 227 | * YUYV image format 228 | */ 229 | public static final int IMF_YUYV=18; 230 | /** 231 | * YYUV image format 232 | */ 233 | public static final int IMF_YYUV=19; 234 | /** 235 | * YVYU image format 236 | */ 237 | public static final int IMF_YVYU=20; 238 | /** 239 | * UYVY image format 240 | */ 241 | public static final int IMF_UYVY=21; 242 | /** 243 | * VYUY image format 244 | */ 245 | public static final int IMF_VYUY=22; 246 | /** 247 | * YUV422 planar image format 248 | */ 249 | public static final int IMF_YUV422P=23; 250 | /** 251 | * YUV411 planar image format 252 | */ 253 | public static final int IMF_YUV411P=24; 254 | /** 255 | * Y41P image format 256 | */ 257 | public static final int IMF_Y41P=25; 258 | /** 259 | * YUV444 image format 260 | */ 261 | public static final int IMF_YUV444=26; 262 | /** 263 | * YUV555 image format 264 | */ 265 | public static final int IMF_YUV555=27; 266 | /** 267 | * YUV565 image format 268 | */ 269 | public static final int IMF_YUV565=28; 270 | /** 271 | * YUV32 image format 272 | */ 273 | public static final int IMF_YUV32=29; 274 | /** 275 | * YUV410 planar image format 276 | */ 277 | public static final int IMF_YUV410=30; 278 | /** 279 | * YUV420 planar image format index 280 | */ 281 | public static final int IMF_YUV420=31; 282 | /** 283 | * HI240 image format 284 | */ 285 | public static final int IMF_HI240=32; 286 | /** 287 | * HM12 image format 288 | */ 289 | public static final int IMF_HM12=33; 290 | 291 | // two planes - Y and Cb/Cr interleaved 292 | /** 293 | * NV12 image format 294 | */ 295 | public static final int IMF_NV12=34; 296 | /** 297 | * NV21 image format 298 | */ 299 | public static final int IMF_NV21=35; 300 | /** 301 | * NV16 image format 302 | */ 303 | public static final int IMF_NV16=36; 304 | /** 305 | * NV61 image format 306 | */ 307 | public static final int IMF_NV61=37; 308 | 309 | // Bayer formats 310 | /** 311 | * SBGGR8 bayer image format 312 | */ 313 | public static final int IMF_SBGGR8=38; 314 | /** 315 | * SGBRG8 image format 316 | */ 317 | public static final int IMF_SGBRG8=39; 318 | /** 319 | * SGRBG8 bayer image format 320 | */ 321 | public static final int IMF_SGRBG8=40; 322 | /** 323 | * SRGGB8 bayer image format 324 | */ 325 | public static final int IMF_SRGGB8=41; 326 | /** 327 | * SBGGR10 bayer image format 328 | */ 329 | public static final int IMF_SBGGR10=42; 330 | /** 331 | * SGBRG10 bayer image format 332 | */ 333 | public static final int IMF_SGBRG10=43; 334 | /** 335 | * SGRBG10 bayer image format 336 | */ 337 | public static final int IMF_SGRBG10=44; 338 | /** 339 | * SRGGB10 bayer image format 340 | */ 341 | public static final int IMF_SRGGB10=45; 342 | /** 343 | * SGRBG10_DPCM8 bayer image format 344 | */ 345 | public static final int IMF_SGRBG10DPCM8=46; 346 | /** 347 | * SBGGR16 bayer image format 348 | */ 349 | public static final int IMF_SBGGR16=47; 350 | 351 | // compressed formats 352 | /** 353 | * MJPEG image format 354 | */ 355 | public static final int IMF_MJPEG=48; 356 | /** 357 | * JPEG image format 358 | */ 359 | public static final int IMF_JPEG=49; 360 | /** 361 | * DV image format 362 | */ 363 | public static final int IMF_DV=50; 364 | /** 365 | * MPEG image format 366 | */ 367 | public static final int IMF_MPEG=51; 368 | 369 | // vendor specific 370 | /** 371 | * CPIA1 image format 372 | */ 373 | public static final int IMF_CPIA1=52; 374 | /** 375 | * WNVA image format 376 | */ 377 | public static final int IMF_WNVA=53; 378 | /** 379 | * SN9C10X image format 380 | */ 381 | public static final int IMF_SN9C10X=54; 382 | /** 383 | * SN9C20X_I420 image format 384 | */ 385 | public static final int IMF_SN9C20X_I420=55; 386 | /** 387 | * PWC1 image format 388 | */ 389 | public static final int IMF_PWC1=56; 390 | /** 391 | * PWC2 image format 392 | */ 393 | public static final int IMF_PWC2=57; 394 | /** 395 | * ET61X251 image format 396 | */ 397 | public static final int IMF_ET61X251=58; 398 | /** 399 | * SPCA501 image format 400 | */ 401 | public static final int IMF_SPCA501=59; 402 | /** 403 | * SPCA505 image format 404 | */ 405 | public static final int IMF_SPCA505=60; 406 | /** 407 | * SPCA508 image format 408 | */ 409 | public static final int IMF_SPCA508=61; 410 | /** 411 | * SPCA561 image format 412 | */ 413 | public static final int IMF_SPCA561=62; 414 | /** 415 | * PAC207 image format 416 | */ 417 | public static final int IMF_PAC207=63; 418 | /** 419 | * MR97310A image format 420 | */ 421 | public static final int IMF_MR97310A=64; 422 | /** 423 | * SN9C2028 image format 424 | */ 425 | public static final int IMF_SN9C2028=65; 426 | /** 427 | * SQ905C image format 428 | */ 429 | public static final int IMF_SQ905C=66; 430 | /** 431 | * PJPG image format 432 | */ 433 | public static final int IMF_PJPG=67; 434 | /** 435 | * OV511 image format 436 | */ 437 | public static final int IMF_OV511=68; 438 | /** 439 | * OV518 image format 440 | */ 441 | public static final int IMF_OV518=69; 442 | /** 443 | * STV0680 image format 444 | */ 445 | public static final int IMF_STV0680=70; 446 | /** 447 | * TM6000 image format 448 | */ 449 | public static final int IMF_TM6000=71; 450 | /** 451 | * CIT_YYVYUY image format 452 | */ 453 | public static final int IMF_CIT_YYVYUY=72; 454 | /** 455 | * KONICA420 image format 456 | */ 457 | public static final int IMF_KONICA420=73; 458 | } 459 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/FrameInterval.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Gilles Gigan (gilles.gigan@gmail.com) 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by the 6 | * Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 11 | * or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | package au.edu.jcu.v4l4j; 19 | 20 | import java.util.List; 21 | import java.util.Vector; 22 | 23 | import au.edu.jcu.v4l4j.ResolutionInfo.DiscreteResolution; 24 | import au.edu.jcu.v4l4j.ResolutionInfo.StepwiseResolution; 25 | import au.edu.jcu.v4l4j.exceptions.UnsupportedMethod; 26 | 27 | /** 28 | * This class encapsulates information about supported frame intervals for a 29 | * given image format and resolution. A frame interval represents the amount of 30 | * time elapsed between two captured frames. It is a floating-point 31 | * number (in seconds) given as a numerator and denominator. Given a frame 32 | * interval 'fi', the corresponding frame rate 'fr' is 'fr = 1 / fi'. 33 | * 34 | * A frame interval object is not directly instantiated. Instead, it can be 35 | * obtained through either a {@link DiscreteResolution} object, a 36 | * {@link StepwiseResolution} object or by calling 37 | * {@link DeviceInfo#listIntervals(ImageFormat, int, int)}. 38 | * @author gilles 39 | * 40 | */ 41 | public class FrameInterval { 42 | 43 | public enum Type{ 44 | /** 45 | * An UNSUPPORTED type means supported frame interval information cannot 46 | * be obtained from the driver. Calling any methods on the 47 | * {@link FrameInterval} object (except 48 | * {@link FrameInterval#getType()} will throw an 49 | * {@link UnsupportedMethod} exception. 50 | */ 51 | UNSUPPORTED, 52 | /** 53 | * A DISCRETE type means frame intervals are reported as a list of 54 | * {@link DiscreteInterval} objects, using 55 | * {@link FrameInterval#getDiscreteIntervals()} 56 | */ 57 | DISCRETE, 58 | /** 59 | * A STEPWISE type means that frame intervals are reported as minimum, 60 | * maximum and step values, encapsulated in a 61 | * {@link StepwiseInterval} object. Use 62 | * {@link FrameInterval#getStepwiseInterval()} to retrieve it. 63 | */ 64 | STEPWISE 65 | }; 66 | 67 | /** 68 | * The type of this frame interval 69 | */ 70 | private final Type type; 71 | 72 | /** 73 | * The list of discrete intervals if type == DISCRETE 74 | */ 75 | private List discreteValues; 76 | 77 | /** 78 | * the stepwise interval object if type == STEPWISE 79 | */ 80 | private StepwiseInterval stepwiseInterval; 81 | 82 | /** 83 | * this method returns the type of the frame interval for the given 84 | * frame resolution. It assumes the query interface is acquired. 85 | * @param o a pointer to a frame_size_discrete or frame_size_stepwise 86 | * struct 87 | * @param t the type of the structure pointed to by 'o': 88 | * 0:frame_size_discrete, 1:frame_size_stepwise (min res), 89 | * 2:frame_size_stepwise (max res) 90 | * @return the interval type (0: unsupported, 1: discrete, 2: continuous) 91 | */ 92 | private native int doGetFrameIntvType(int t, long o); 93 | 94 | /** 95 | * this method populates the discreteIntervals member for the given 96 | * frame resolution. It assumes the query interface is acquired. 97 | * @param o a pointer to a frame_size_discrete or frame_size_stepwise 98 | * struct 99 | * @param t the type of the structure pointed to by 'o': 100 | * 0:frame_size_discrete, 1:frame_size_stepwise (min res), 101 | * 2:frame_size_stepwise (max res) 102 | */ 103 | private native void doGetDiscrete(int t, long o); 104 | 105 | /** 106 | * this method populates the continuousInterval member for the given 107 | * frame resolution. It assumes the query interface is acquired. 108 | * @param o a pointer to a frame_size_discrete or frame_size_stepwise 109 | * struct 110 | * @param t the type of the structure pointed to by 'o': 111 | * 0:frame_size_discrete, 1:frame_size_stepwise (min res), 112 | * 2:frame_size_stepwise (max res) 113 | */ 114 | private native void doGetStepwise(int t, long o); 115 | 116 | /** 117 | * This method builds a new FrameInterval object. 118 | * It must be called while libvideo's query interface is acquired ! 119 | * @param o a JNI pointer to a frame_size_discrete or frame_size_stepwise 120 | * @param ptr_type the type of the structure pointed to by 'o': 121 | * 0: o points to a struct frame_size_discrete and a FrameInterval 122 | * object matching the interval_type in this structure is to be constructed 123 | * 1: o points to a struct frame_size_continuous and a FrameInterval 124 | * object matching the interval_type_min_res in this structure is to be 125 | * constructed 126 | * 2: o points to a struct frame_size_continuous and a FrameInterval 127 | * object matching the interval_type_max_res in this structure is to be 128 | * constructed 129 | * 3: o points to NULL and the constructed object will be of type 130 | * {@link Type#UNSUPPORTED}. 131 | * 4: o points to a struct frame_intv_discrete and a matching FrameInterval 132 | * object is to be constructed 133 | * 5: o points to a struct frame_intv_continuous and a matching FrameInterval 134 | * object is to be constructed 135 | */ 136 | FrameInterval(int ptr_type, long o){ 137 | int frameIntvType; 138 | 139 | //check the pointer type 140 | switch(ptr_type){ 141 | case 3: 142 | frameIntvType = 0; //UNSUPPORTED 143 | break; 144 | case 4: 145 | frameIntvType = 1; //DISCRETE 146 | break; 147 | case 5: 148 | frameIntvType = 2; //STEPWISE 149 | break; 150 | default: 151 | try { 152 | frameIntvType = doGetFrameIntvType(ptr_type, o); 153 | } catch (Exception e){ 154 | //error checking frame interval type 155 | e.printStackTrace(); 156 | System.err.println("There was an error checking the supported" 157 | +" interval types.\nPlease report this error to the" 158 | +"v4l4j mailing list.\nSee REAME file for " 159 | +"information on reporting bugs"); 160 | type = Type.UNSUPPORTED; 161 | return; 162 | } 163 | } 164 | 165 | try { 166 | if(frameIntvType==1){ 167 | discreteValues = new Vector(); 168 | doGetDiscrete(ptr_type, o); 169 | } else if(frameIntvType==2){ 170 | doGetStepwise(ptr_type, o); 171 | } 172 | } catch (Exception e){ 173 | //error checking supported intervals 174 | e.printStackTrace(); 175 | System.err.println("There was an error checking the supported" 176 | +" intervals.\nPlease report this error to the" 177 | +"v4l4j mailing list.\nSee REAME file for " 178 | +"information on reporting bugs"); 179 | type = Type.UNSUPPORTED; 180 | return; 181 | } 182 | 183 | if(frameIntvType==0) 184 | type = Type.UNSUPPORTED; 185 | else if(frameIntvType==1){ 186 | type = Type.DISCRETE; 187 | } else { 188 | type = Type.STEPWISE; 189 | } 190 | } 191 | 192 | /** 193 | * This method returns the {@link Type} of this frame interval object. 194 | * @return the {@link Type} of this frame interval object. 195 | */ 196 | public Type getType(){ 197 | return type; 198 | } 199 | 200 | /** 201 | * This method returns a list of {@link DiscreteInterval}s, or throws a 202 | * {@link UnsupportedMethod} exception if this frame interval object 203 | * is not of type {@link Type#DISCRETE}. 204 | * @return a list of {@link DiscreteInterval}s 205 | * @throws UnsupportedMethod if this frame interval object 206 | * is not of type {@link Type#DISCRETE}. 207 | */ 208 | public List getDiscreteIntervals(){ 209 | if(type!=Type.DISCRETE) 210 | throw new UnsupportedMethod("Supported intervals are not discrete"); 211 | return new Vector(discreteValues); 212 | } 213 | 214 | 215 | /** 216 | * This method returns a {@link StepwiseInterval} object, or throws a 217 | * {@link UnsupportedMethod} exception if this frame interval object 218 | * is not of type {@link Type#STEPWISE}. 219 | * @return a {@link StepwiseInterval} object 220 | * @throws UnsupportedMethod if this frame interval object 221 | * is not of type {@link Type#STEPWISE}. 222 | */ 223 | public StepwiseInterval getStepwiseInterval(){ 224 | if(type!=Type.STEPWISE) 225 | throw new UnsupportedMethod("Supported interval is not continuous"); 226 | return stepwiseInterval; 227 | } 228 | 229 | @Override 230 | public String toString(){ 231 | String s; 232 | if(type==Type.DISCRETE){ 233 | s = ""; 234 | for(DiscreteInterval i: discreteValues) 235 | s += i.toString() + " - "; 236 | } else if(type==Type.STEPWISE){ 237 | s = stepwiseInterval.toString(); 238 | } else 239 | s = "no frame interval information"; 240 | return s; 241 | } 242 | 243 | 244 | /** 245 | * This class encapsulates information about a discrete frame interval, 246 | * expressed as a numerator and denominator. {@link DiscreteInterval} 247 | * objects are not instantiated directly, instead these objects can be 248 | * obtained through a {@link FrameInterval} object. 249 | * 250 | * @author gilles 251 | * 252 | */ 253 | public static class DiscreteInterval { 254 | /** 255 | * The numerator for this discrete frame interval. 256 | */ 257 | public final int numerator; 258 | 259 | /** 260 | * The denominator for this discrete frame interval. 261 | */ 262 | public final int denominator; 263 | 264 | DiscreteInterval(int n, int d){ 265 | numerator = n; 266 | denominator = d; 267 | } 268 | 269 | /** 270 | * This method returns the numerator of this frame interval. 271 | * @return the numerator of the frame interval 272 | */ 273 | public int getNum(){ 274 | return numerator; 275 | } 276 | 277 | /** 278 | * This method returns the denominator of this frame interval. 279 | * @return the denominator of this frame interval 280 | */ 281 | public int getDenom(){ 282 | return denominator; 283 | } 284 | 285 | @Override 286 | public String toString(){ 287 | return numerator+"/"+denominator; 288 | } 289 | 290 | @Override 291 | public int hashCode() { 292 | final int prime = 31; 293 | int result = 1; 294 | result = prime * result + denominator; 295 | result = prime * result + numerator; 296 | return result; 297 | } 298 | 299 | @Override 300 | public boolean equals(Object obj) { 301 | if (this == obj) 302 | return true; 303 | if (obj == null) 304 | return false; 305 | if (!(obj instanceof DiscreteInterval)) 306 | return false; 307 | DiscreteInterval other = (DiscreteInterval) obj; 308 | if (denominator != other.denominator) 309 | return false; 310 | if (numerator != other.numerator) 311 | return false; 312 | return true; 313 | } 314 | } 315 | 316 | /** 317 | * A continuous frame interval is a bounded frame interval. It has 318 | * minimum, maximum and step values, all expressed as numerator/denominator 319 | * pairs contained in a {@link DiscreteInterval} object. A continuous 320 | * interval object encapsulates the bounds for a continuous frame interval. 321 | * @author gilles 322 | * 323 | */ 324 | public static class StepwiseInterval { 325 | /** 326 | * The minimum frame interval value 327 | */ 328 | public final DiscreteInterval minIntv; 329 | 330 | /** 331 | * The maximum frame interval value 332 | */ 333 | public final DiscreteInterval maxIntv; 334 | 335 | /** 336 | * The step frame interval value 337 | */ 338 | public final DiscreteInterval stepIntv; 339 | 340 | private StepwiseInterval(int minN, int minD, int maxN, int maxD, 341 | int stepN, int stepD) { 342 | minIntv = new DiscreteInterval(minN, minD); 343 | maxIntv = new DiscreteInterval(maxN, maxD); 344 | stepIntv = new DiscreteInterval(stepN, stepD); 345 | } 346 | 347 | /** 348 | * This continuous frame interval has a minimum bound. This method 349 | * returns it. 350 | * @return the minimum value of this continuous frame interval 351 | */ 352 | public DiscreteInterval getMinInterval(){ 353 | return minIntv; 354 | } 355 | 356 | /** 357 | * This continuous frame interval has a maximum bound. This method 358 | * returns it. 359 | * @return the minimum value of this continuous frame interval 360 | */ 361 | public DiscreteInterval getMaxInterval(){ 362 | return maxIntv; 363 | } 364 | 365 | /** 366 | * This continuous frame interval has a maximum bound. This method 367 | * returns it. 368 | * @return the minimum value of this continuous frame interval 369 | */ 370 | public DiscreteInterval getStepInterval(){ 371 | return stepIntv; 372 | } 373 | 374 | @Override 375 | public String toString(){ 376 | return minIntv+" - "+maxIntv+" - "+stepIntv; 377 | } 378 | 379 | @Override 380 | public int hashCode() { 381 | final int prime = 31; 382 | int result = 1; 383 | result = prime * result 384 | + ((maxIntv == null) ? 0 : maxIntv.hashCode()); 385 | result = prime * result 386 | + ((minIntv == null) ? 0 : minIntv.hashCode()); 387 | result = prime * result 388 | + ((stepIntv == null) ? 0 : stepIntv.hashCode()); 389 | return result; 390 | } 391 | 392 | @Override 393 | public boolean equals(Object obj) { 394 | if (this == obj) 395 | return true; 396 | if (obj == null) 397 | return false; 398 | if (!(obj instanceof StepwiseInterval)) 399 | return false; 400 | StepwiseInterval other = (StepwiseInterval) obj; 401 | if (maxIntv == null) { 402 | if (other.maxIntv != null) 403 | return false; 404 | } else if (!maxIntv.equals(other.maxIntv)) 405 | return false; 406 | if (minIntv == null) { 407 | if (other.minIntv != null) 408 | return false; 409 | } else if (!minIntv.equals(other.minIntv)) 410 | return false; 411 | if (stepIntv == null) { 412 | if (other.stepIntv != null) 413 | return false; 414 | } else if (!stepIntv.equals(other.stepIntv)) 415 | return false; 416 | return true; 417 | } 418 | } 419 | 420 | } 421 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/FrameGrabber.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2008 Gilles Gigan (gilles.gigan@gmail.com) 3 | * eResearch Centre, James Cook University (eresearch.jcu.edu.au) 4 | * 5 | * This program was developed as part of the ARCHER project 6 | * (Australian Research Enabling Environment) funded by a 7 | * Systemic Infrastructure Initiative (SII) grant and supported by the Australian 8 | * Department of Innovation, Industry, Science and Research 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17 | * or FITNESS FOR A PARTICULAR PURPOSE. 18 | * See the GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | * 23 | */ 24 | 25 | package au.edu.jcu.v4l4j; 26 | 27 | import au.edu.jcu.v4l4j.VideoFrame; 28 | import au.edu.jcu.v4l4j.FrameInterval.DiscreteInterval; 29 | import au.edu.jcu.v4l4j.exceptions.CaptureChannelException; 30 | import au.edu.jcu.v4l4j.exceptions.VideoStandardException; 31 | import au.edu.jcu.v4l4j.exceptions.InvalidValue; 32 | import au.edu.jcu.v4l4j.exceptions.NoTunerException; 33 | import au.edu.jcu.v4l4j.exceptions.StateException; 34 | import au.edu.jcu.v4l4j.exceptions.UnsupportedMethod; 35 | import au.edu.jcu.v4l4j.exceptions.V4L4JException; 36 | 37 | /** 38 | * Objects implementing this interface provide methods to capture frames from 39 | * a {@link VideoDevice}. FrameGrabbers are not instantiated 40 | * directly. Instead, one of the getXXXFrameGrabber() methods 41 | * must be called on a {@link VideoDevice} to obtain one. The requested height 42 | * and width may be adjusted to the closest supported values. The adjusted width 43 | * and height can be retrieved by calling {@link #getWidth()} and 44 | * {@link #getHeight()}.
45 | * Frame grabbers operate in push mode: you must give v4l4j 46 | * an object implementing the {@link CaptureCallback} interface by calling 47 | * {@link #setCaptureCallback(CaptureCallback)}. During capture, 48 | * v4l4j will create a thread and deliver new frames to the capture callback 49 | * object. By default, new threads are created by the thread factory returned by 50 | * Executors.defaultThreadFactory(), but you can 51 | * provide your own thread factory by calling 52 | * {@link VideoDevice#setThreadFactory(java.util.concurrent.ThreadFactory factory)} 53 | * prior to creating a FrameGrabber object.
54 | * A typical FrameGrabber use case is as follows: 55 | *
56 | * Create the video device and frame grabber: 57 | *

58 | * //create a new video device
59 | * VideoDevice vd = new VideoDevice("/dev/video0");
60 | * // vd.setThreadFactory(myThreadFactory); // set your own thread factory if required. 61 | *
//Create an instance of FrameGrabber 62 | *
FrameGrabber f = vd.getJPEGFrameGrabber(320, 240, 0, 0, 80); 63 | *
//If supported, this frame grabber will capture frames and convert them 64 | *
//to JPEG before delivering them to your application. 65 | *
66 | *
//Instantiate an object that implements the {@link CaptureCallback} 67 | *
//interface which will receive captured frame 68 | *
myCallbackObject = new MyCallbackObjectclass(); 69 | *
70 | *
//pass it to the frame grabber. 71 | *
f.setCaptureCallback(myCallbackObject); 72 | *
73 | *
//Now start the capture 74 | *
f.startCapture(); 75 | *
76 | *
//At this stage, myCallbackObject.nextFrame() will be called every time 77 | *
//a new frame is available (see next paragraph). 78 | *
79 | *
//When appropriate, stop the capture 80 | *
f.stopCapture(); 81 | *
//Release the frame grabber 82 | *
vd.releaseFrameGrabber(); 83 | *
//Release the video device 84 | *
vd.release(); 85 | *


86 | * In myCallbackObject, when the capture is started, the following method is 87 | * called every time a new frame is available :
88 | * 89 | *
public void nextFrame(VideoFrame frame) { 90 | *
   //do something useful with frame. But make sure you recycle 91 | *
   //it when dealt with, so v4l4j can re-use it later on 92 | *
   frame.recycle(); 93 | *
}
94 | *
95 | 96 | * For a concrete example of push mode capture which displays the video 97 | * stream, see the au.edu.jcu.v4l4j.examples.SimpleViewer example application. 98 | *
Again, you must recycle video frames when they are no 99 | * longer used.

100 | * 101 | * Only one frame grabber can be used at any one time on a given video device. 102 | * Once a frame grabber is released with 103 | * {@link VideoDevice#releaseFrameGrabber()}, another one can be obtained. 104 | * However, when the capture is stopped with {@link #stopCapture()}, it can be 105 | * started again with {@link #stopCapture()} without having to create a new 106 | * frame grabber. 107 | * 108 | * @see RawFrameGrabber 109 | * @see JPEGFrameGrabber 110 | * @see RGBFrameGrabber 111 | * @see BGRFrameGrabber 112 | * @see YUVFrameGrabber 113 | * @see YVUFrameGrabber 114 | * @author gilles 115 | * 116 | */ 117 | public interface FrameGrabber { 118 | 119 | /** 120 | * This method returns the native image format used by this 121 | * FrameGrabber. The returned format specifies the image format in which 122 | * frames are obtained from the device. 123 | * @return the native image format used by this FrameGrabber. 124 | * @throws StateException if this 125 | * FrameGrabber has been already released, and therefore must 126 | * not be used anymore. 127 | */ 128 | public ImageFormat getImageFormat(); 129 | 130 | /** 131 | * This method returns the number of buffers v4l4j has negotiated with 132 | * the driver. The driver stores captured frames in these buffers and returns 133 | * them to v4l4j. A {@link VideoFrame} represents (and encapsulates) one of 134 | * these buffers. Hence, this number is an indication of how many video 135 | * frames can be delivered by v4l4j to your application before the capture 136 | * blocks until a buffer is returned to the driver. Practically speaking, 137 | * this number specifies how many times v4l4j can call 138 | * {@link CaptureCallback#nextFrame(VideoFrame frame)} and block waiting for 139 | * one of the previous frames to be recycled through {@link VideoFrame#recycle()}.
140 | * You can specify how many buffers the driver should use by 141 | * setting the v4l4j.num_driver_buffers property to an integer value 142 | * before creating a frame grabber object. The number you specify is only an 143 | * indication, and the driver can decide to allocate a different number of buffers. 144 | * Before setting this number, make sure you fully understand the implications of doing this. 145 | * @return the number of frame buffers used to retrieve frames from 146 | * the driver 147 | */ 148 | public int getNumberOfVideoFrames(); 149 | 150 | /** 151 | * This method returns the number of recycled video frames, ie. the number 152 | * of video frames are currently available to v4l4j (and the driver) to 153 | * store new incoming frames. 154 | * This number indicates how many more frames can be captured by v4l4j 155 | * before the capture stops until you recycle one of the previous frame that was 156 | * delivered to your application by calling {@link VideoFrame#recycle()}. 157 | * @return the number of video frames currently recycled. 158 | * @see #getNumberOfVideoFrames() 159 | */ 160 | public int getNumberOfRecycledVideoFrames(); 161 | 162 | /** 163 | * This method sets the frame interval used for capture. The frame interval 164 | * defined the lapse of time (in second) between two captured frames and is 165 | * the inverse of the frame rate. It may or may not be supported by the 166 | * underlying hardware/driver. If not supported, calling this method 167 | * throws a {@link UnsupportedMethod} exception. This method will throw an 168 | * {@link InvalidValue} exception if the given frame interval value is not 169 | * supported. 170 | * As a guide, you can check the {@link ResolutionInfo} objects associated 171 | * with the video device to find out whether frame intervals are at all 172 | * supported, and if they are, what values (or range of values) are accepted. 173 | * {@link ResolutionInfo} objects can be obtained for each 174 | * {@link ImageFormat}. See the {@link ImageFormat} and 175 | * {@link ResolutionInfo} documentation for more information. 176 | * @param num the numerator of the frame interval to be set 177 | * @param denom the denominator of the frame interval to be set 178 | * @throws UnsupportedMethod if setting the frame interval is not supported. 179 | * @throws InvalidValue if the given frame interval value is invalid. 180 | * @throws StateException if capture is ongoing (the frame interval must be 181 | * set when not capturing), or if this 182 | * FrameGrabber has been already released, and therefore must 183 | * not be used anymore. 184 | */ 185 | public void setFrameInterval(int num, int denom) throws InvalidValue; 186 | 187 | /** 188 | * This method returns the current frame interval used for capture. 189 | * It may or may not be supported by the 190 | * underlying hardware/driver. If not supported, calling this method 191 | * throws a {@link UnsupportedMethod} exception. 192 | * @throws UnsupportedMethod if setting the frame interval is not supported. 193 | * @throws StateException if capture is ongoing (the frame interval must be 194 | * queried when not capturing), or if this 195 | * FrameGrabber has been already released, and therefore must 196 | * not be used anymore. 197 | */ 198 | public DiscreteInterval getFrameInterval(); 199 | 200 | /** 201 | * This method adjusts the current video input number and video standard. 202 | * @throws VideoStandardException if the chosen video standard is not 203 | * supported 204 | * @throws CaptureChannelException if the given channel number value is not 205 | * valid 206 | */ 207 | public void setVideoInputNStandard(int inputNumber, int standard) throws VideoStandardException, CaptureChannelException; 208 | 209 | /** 210 | * This method retrieves the current video input channel number. 211 | * @return the current input number 212 | */ 213 | public int getVideoInput(); 214 | 215 | /** 216 | * This method retrieves the current video standard used by the current video input. 217 | * @return the current standard 218 | */ 219 | public int getVideoStandard(); 220 | 221 | /** 222 | * This method returns the {@link Tuner} associated with the input of this 223 | * FrameGrabber, or throws a {@link NoTunerException} if there 224 | * is none. 225 | * @return the {@link Tuner} object associated with the chosen input. 226 | * @throws NoTunerException if the selected input does not have a tuner 227 | * @throws StateException if this 228 | * FrameGrabber has been already released, and therefore must 229 | * not be used anymore. 230 | */ 231 | public Tuner getTuner() throws NoTunerException; 232 | 233 | /** 234 | * setCaptureCallback sets the {@link CaptureCallback} object 235 | * which will be notified by this grabber as soon as new frames become 236 | * available.
237 | * This method cannot be called while the capture is active, ie. in between 238 | * a call to {@link #startCapture()} and {@link #stopCapture()}. 239 | * @param callback an object implementing the {@link CaptureCallback} 240 | * interface which will receive new frames and capture exceptions. 241 | * @throws StateException if this method is invoked while capture is active, 242 | * ie. after a call to {@link #startCapture()} and prior a call 243 | * to {@link #stopCapture()}. 244 | */ 245 | public void setCaptureCallback(CaptureCallback callback); 246 | 247 | /** 248 | * This method starts the capture. Frames will 249 | * be delivered to the provided {@link CaptureCallback} object. 250 | * @throws V4L4JException if no valid {@link CaptureCallback} object was 251 | * provided (call {@link #setCaptureCallback(CaptureCallback callback)} 252 | * OR if the capture cannot be started 253 | * @throws StateException if this FrameGrabber has been already 254 | * released, and therefore must not be used anymore 255 | */ 256 | public void startCapture() throws V4L4JException; 257 | 258 | /** 259 | * This method stops the capture, and recycles all @link {@link VideoFrame}s. 260 | * @throws StateException if the capture has not been started, is already 261 | * stopped, or if this FrameGrabber has been already released, 262 | * and therefore must not be used anymore. 263 | */ 264 | public void stopCapture(); 265 | 266 | /** 267 | * This method returns the actual height of captured frames. 268 | * @return the height 269 | * @throws StateException if this 270 | * FrameGrabber has been already released, and therefore must 271 | * not be used anymore. 272 | */ 273 | public int getHeight(); 274 | 275 | /** 276 | * This method returns the actual width of captured frames. 277 | * @return the width 278 | * @throws StateException if this 279 | * FrameGrabber has been already released, and therefore must 280 | * not be used anymore. 281 | */ 282 | public int getWidth(); 283 | 284 | /** 285 | * This method returns the video channel used to capture frames. 286 | * @return the channel 287 | * @throws StateException if this 288 | * FrameGrabber has been already released, and therefore must 289 | * not be used anymore. 290 | */ 291 | public int getChannel(); 292 | 293 | /** 294 | * This method returns the actual video standard: 295 | * {@link V4L4JConstants#STANDARD_NTSC}, {@link V4L4JConstants#STANDARD_PAL} 296 | * , {@link V4L4JConstants#STANDARD_SECAM} or 297 | * {@link V4L4JConstants#STANDARD_WEBCAM} 298 | * @return the video standard 299 | * @throws StateException if this 300 | * FrameGrabber has been already released, and therefore must 301 | * not be used anymore. 302 | */ 303 | public int getStandard(); 304 | 305 | } 306 | -------------------------------------------------------------------------------- /src/main/java/au/edu/jcu/v4l4j/ResolutionInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2008 Gilles Gigan (gilles.gigan@gmail.com) 3 | * eResearch Centre, James Cook University (eresearch.jcu.edu.au) 4 | * 5 | * This program was developed as part of the ARCHER project 6 | * (Australian Research Enabling Environment) funded by a 7 | * Systemic Infrastructure Initiative (SII) grant and supported by the Australian 8 | * Department of Innovation, Industry, Science and Research 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17 | * or FITNESS FOR A PARTICULAR PURPOSE. 18 | * See the GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | * 23 | */ 24 | 25 | package au.edu.jcu.v4l4j; 26 | 27 | import java.util.List; 28 | import java.util.Vector; 29 | 30 | import au.edu.jcu.v4l4j.exceptions.UnsupportedMethod; 31 | 32 | /** 33 | * This class encapsulates information about the supported capture resolutions 34 | * and frame intervals for a given {@link ImageFormat}. The first step is to 35 | * determine how the supported resolutions are expressed by calling 36 | * {@link #getType()}. This method returns either: 37 | *
    38 | *
  • {@link Type#UNSUPPORTED}: no resolution information can be obtained from 39 | * the driver. Calling any methods (except {@link #getType()}) will throw a 40 | * {@link UnsupportedMethod} exception.
  • 41 | *
  • {@link Type#DISCRETE}: supported resolutions and frame intervals are 42 | * returned as a list of {@link DiscreteResolution} objects, which encapsulate 43 | * the width and height for this resolution as well as supported frame intervals. 44 | * Calling {@link #getDiscreteResolutions()} returns this list.
  • 45 | *
  • {@link Type#STEPWISE}: supported width and height values can be anywhere 46 | * within a given minimum and maximum using a step value. These values, along 47 | * with information on supported frame intervals are encapsulated in a 48 | * {@link StepwiseResolution} object which is retrieved by calling 49 | * {@link #getStepwiseResolution()}.
  • 50 | *
51 | * {@link StepwiseResolution} and {@link DiscreteResolution} objects provide 52 | * information on supported capture resolutions and frame intervals for a given 53 | * image format.
54 | * {@link ResolutionInfo} objects are not instantiated directly. Instead, each 55 | * {@link ImageFormat} carries a reference to a {@link ResolutionInfo} object, 56 | * describing the supported resolutions for this format. A list of supported 57 | * image formats is obtained by calling {@link DeviceInfo#getFormatList()} on 58 | * a {@link VideoDevice}. See the {@link ImageFormatList} documentation for 59 | * more information. 60 | * @author gilles 61 | * 62 | */ 63 | public class ResolutionInfo { 64 | /** 65 | * The Type enumeration defines how the supported resolutions are expressed. 66 | * If DISCRETE, then supported resolutions are reported as a list of 67 | * {@link DiscreteResolution} objects. If STEPWISE, then minimum, maximum 68 | * and step values for width and height are reported. If UNSUPPORTED, then 69 | * resolution information is not available. 70 | * @author gilles 71 | * 72 | */ 73 | public enum Type{ 74 | /** 75 | * An UNSUPPORTED type means supported resolution information cannot be 76 | * obtained from the driver. Calling any methods on the 77 | * {@link ResolutionInfo} object (except 78 | * {@link ResolutionInfo#getType()} will throw an 79 | * {@link UnsupportedMethod} exception. 80 | */ 81 | UNSUPPORTED, 82 | /** 83 | * A DISCRETE type means resolutions are reported as a list of 84 | * {@link DiscreteResolution} objects, using 85 | * {@link ResolutionInfo#getDiscreteResolutions()} 86 | */ 87 | DISCRETE, 88 | /** 89 | * A STEPWISE type means that resolutions are reported as minimum, 90 | * maximum and step values for width and height through a 91 | * {@link StepwiseResolution} object. This object can be obtained by 92 | * calling {@link ResolutionInfo#getStepwiseResolution()}. 93 | */ 94 | STEPWISE 95 | }; 96 | 97 | /** 98 | * The resolution information type 99 | */ 100 | private final Type type; 101 | 102 | /** 103 | * The stepwise resolution object 104 | * Valid only if type==STEPWISE 105 | */ 106 | private StepwiseResolution stepwiseObject; 107 | 108 | /** 109 | * A list of {@link DiscreteResolution} object if type==DISCRETE 110 | */ 111 | private List discreteValues; 112 | 113 | /** 114 | * This native method returns the type of the supported resolutions. 115 | * @param o a C pointer to a struct v4l4j_device 116 | * @return 0: unsupported, 1: discrete, 2: continuous 117 | */ 118 | private native int doGetType(int index, long o); 119 | 120 | /** 121 | * This native method sets the stepwise attributes (min, max & step width 122 | * & height) 123 | * @param index the image format index 124 | * @param o a C pointer to a struct v4l4j_device 125 | */ 126 | private native void doGetStepwise(int index, long o); 127 | 128 | /** 129 | * This native method sets the discrete resolution list (discreteValues) 130 | * @param index the image format index 131 | * @param o a C pointer to a struct v4l4j_device 132 | */ 133 | private native void doGetDiscrete(int index, long o); 134 | 135 | /** 136 | * This method builds a new resolution information object. It MUST be called 137 | * while the device info interface of libvideo is acquired. 138 | * @param index the libvideo index of the image format for which this 139 | * resolution info object is to be constructed 140 | * @param o a C pointer to a struct v4l4j_device 141 | */ 142 | ResolutionInfo(int index, long o){ 143 | int t; 144 | try { 145 | t = doGetType(index, o); 146 | if(t==1){ 147 | discreteValues = new Vector(); 148 | doGetDiscrete(index,o); 149 | } else if(t==2){ 150 | doGetStepwise(index,o); 151 | } 152 | } catch (Exception e){ 153 | //error checking supported resolutions 154 | e.printStackTrace(); 155 | System.err.println("There was an error checking the supported" 156 | +" resolutions.\nPlease report this error to the" 157 | +"v4l4j mailing list.\nSee REAME file for " 158 | +"information on reporting bugs"); 159 | type = Type.UNSUPPORTED; 160 | return; 161 | } 162 | 163 | if(t==0) 164 | type = Type.UNSUPPORTED; 165 | else if(t==1){ 166 | type = Type.DISCRETE; 167 | } else { 168 | type = Type.STEPWISE; 169 | } 170 | } 171 | 172 | /** 173 | * This method returns the resolution information type. See {@link Type} 174 | * enumeration. 175 | * @return the resolution information type. See {@link Type}. 176 | */ 177 | public Type getType(){ 178 | return type; 179 | } 180 | 181 | /** 182 | * This method returns a list of {@link DiscreteResolution}s, or throws a 183 | * {@link UnsupportedMethod} exception if this resolution info object 184 | * is not of type {@link Type#DISCRETE}. 185 | * @return a list of {@link DiscreteResolution}s 186 | * @throws UnsupportedMethod if this resolution info object 187 | * is not of type {@link Type#DISCRETE}. 188 | */ 189 | public List getDiscreteResolutions() 190 | throws UnsupportedMethod{ 191 | if(type!=Type.DISCRETE) 192 | throw new UnsupportedMethod("Supported resolutions are not discrete"); 193 | return new Vector(discreteValues); 194 | } 195 | 196 | /** 197 | * This method returns a {@link StepwiseResolution} object, or throws a 198 | * {@link UnsupportedMethod} exception if this resolution info object 199 | * is not of type {@link Type#STEPWISE}. 200 | * @return a {@link StepwiseResolution} object 201 | * @throws UnsupportedMethod if this resolution info object 202 | * is not of type {@link Type#STEPWISE}. 203 | */ 204 | public StepwiseResolution getStepwiseResolution() throws UnsupportedMethod{ 205 | if(type!=Type.STEPWISE) 206 | throw new UnsupportedMethod("Supported resolutions are not stepwsie"); 207 | return stepwiseObject; 208 | } 209 | 210 | @Override 211 | public String toString(){ 212 | String s; 213 | if(type==Type.STEPWISE){ 214 | s = stepwiseObject.toString(); 215 | } else if(type == Type.DISCRETE){ 216 | s = ""; 217 | for(DiscreteResolution d: discreteValues) 218 | s += d+" - "; 219 | } else { 220 | s = "no resolution information"; 221 | } 222 | return s; 223 | } 224 | 225 | /** 226 | * This class represents a possible resolution supported by a video device. 227 | * It also contains information on supported frame intervals at this 228 | * resolution, encapsulated in a {@link FrameInterval} object returned by 229 | * the {@link #getFrameInterval()} method.
230 | * A {@link DiscreteResolution} object is not instantiated directly. 231 | * Instead, a list of supported {@link DiscreteResolution}s for a given 232 | * video device can be obtained through a {@link ResolutionInfo} for that 233 | * device. 234 | * @author gilles 235 | */ 236 | public static class DiscreteResolution{ 237 | 238 | /** 239 | * The resolution width 240 | */ 241 | public final int width; 242 | 243 | /** 244 | * The resolution height 245 | */ 246 | public final int height; 247 | 248 | /** 249 | * The frame interval object containing information on supported 250 | * frame intervals for capture at this resolution. 251 | */ 252 | public final FrameInterval interval; 253 | 254 | private DiscreteResolution(int w, int h, FrameInterval f){ 255 | width = w; 256 | height = h; 257 | interval = f; 258 | } 259 | 260 | /** 261 | * This method returns the resolution width 262 | * @return the resolution width 263 | */ 264 | public int getWidth(){ 265 | return width; 266 | } 267 | 268 | /** 269 | * This method returns the resolution height 270 | * @return the resolution height 271 | */ 272 | public int getHeight(){ 273 | return height; 274 | } 275 | 276 | /** 277 | * This method returns the frame interval object, containing 278 | * information on supported frame intervals for this discrete 279 | * resolution. 280 | * @return the frame intervals supported at this resolution 281 | */ 282 | public FrameInterval getFrameInterval(){ 283 | return interval; 284 | } 285 | 286 | @Override 287 | public String toString(){ 288 | return width+"x"+height +" ("+interval+")"; 289 | } 290 | } 291 | 292 | /** 293 | * This class encapsulates information about supported capture resolutions 294 | * for a video device. The supported resolutions are continuous values, 295 | * comprised between a minimum and a maximum, in given increments (called 296 | * the step value).
297 | * For instance, for a device supporting capture resolutions between 160x120 and 298 | * 800x600 in increments of 160x120, the following resolutions are 299 | * supported: 160x120, 320x240, 480x360, 640x480, 800x600.
300 | * A StepwiseResolution object matching the above criteria will 301 | * contain: 302 | *
    303 | *
  • StepwiseResolution.minWidth = 160
  • 304 | *
  • StepwiseResolution.minHeight = 120
  • 305 | *
  • StepwiseResolution.stepWidth = 160
  • 306 | *
  • StepwiseResolution.stepHeight= 120
  • 307 | *
  • StepwiseResolution.maxWidth = 800
  • 308 | *
  • StepwiseResolution.maxHeight = 600
  • 309 | *
310 | * These values can also be obtained using the accessor methods. 311 | *

312 | * Objects of this class also contains two {@link FrameInterval} objects 313 | * providing information on supported frame intervals for capture 314 | * at the minimum resolution 315 | * ({@link StepwiseResolution#getMinResFrameInterval()}) and maximum 316 | * resolution ({@link StepwiseResolution#getMaxResFrameInterval()}). 317 | * You can find out supported frame intervals for any other intermediate 318 | * resolution by calling 319 | * {@link DeviceInfo#listIntervals(ImageFormat, int, int)}. 320 | * A StepwiseResolution object is not directly instantiated. Instead, it can 321 | * be obtained through a {@link ResolutionInfo}. 322 | * @author gilles 323 | */ 324 | public static class StepwiseResolution{ 325 | /** 326 | * The minimum, maximum and step values for both width and height 327 | */ 328 | public final int minWidth, maxWidth, stepWidth, minHeight, maxHeight, stepHeight; 329 | 330 | /** 331 | * The frame interval object containing information on supported 332 | * frame intervals for capture at the minimum resolution 333 | * (minWidth x minHeight). 334 | */ 335 | public final FrameInterval minInterval; 336 | 337 | /** 338 | * The frame interval object containing information on supported 339 | * frame intervals for capture at the maximum resolution 340 | * (maxWidth x maxHeight). 341 | */ 342 | public final FrameInterval maxInterval; 343 | 344 | StepwiseResolution(int minw, int minh, int maxw, int maxh, 345 | int stepw, int steph, FrameInterval minI, FrameInterval maxI){ 346 | minWidth = minw; 347 | maxWidth = maxw; 348 | stepWidth = stepw; 349 | minHeight = minh; 350 | maxHeight = maxh; 351 | stepHeight = steph; 352 | minInterval = minI; 353 | maxInterval = maxI; 354 | } 355 | 356 | /** 357 | * This method returns the minimum width. 358 | * @return the minimum width 359 | */ 360 | public int getMinWidth(){ 361 | return minWidth; 362 | } 363 | 364 | /** 365 | * This method returns the maximum width. 366 | * @return the maximum width 367 | */ 368 | public int getMaxWidth(){ 369 | return maxWidth; 370 | } 371 | 372 | /** 373 | * This method returns the width step. 374 | * @return the width step 375 | */ 376 | public int getWidthStep(){ 377 | return stepWidth; 378 | } 379 | 380 | /** 381 | * This method returns the minimum height. 382 | * @return the minimum height 383 | */ 384 | public int getMinHeight(){ 385 | return minHeight; 386 | } 387 | 388 | /** 389 | * This method returns the maximum height. 390 | * @return the maximum height 391 | */ 392 | public int getMaxHeight(){ 393 | return maxHeight; 394 | } 395 | 396 | /** 397 | * This method returns the height step. 398 | * @return the height step 399 | */ 400 | public int getHeightStep(){ 401 | return stepHeight; 402 | } 403 | 404 | /** 405 | * This method returns the frame interval object, containing 406 | * information on all supported frame interval at the minimum 407 | * resolution (minWidth x minHeight) 408 | * @return the frame interval supported at the minimum 409 | * resolution (minWidth x minHeight) 410 | */ 411 | public FrameInterval getMinResFrameInterval(){ 412 | return minInterval; 413 | } 414 | 415 | /** 416 | * This method returns the frame interval object, containing 417 | * information on all supported frame interval at the maximum 418 | * resolution (maxWidth x maxHeight) 419 | * @return the frame interval supported at the maximum 420 | * resolution (maxWidth x maxHeight) 421 | */ 422 | public FrameInterval getMaxResFrameInterval(){ 423 | return maxInterval; 424 | } 425 | 426 | @Override 427 | public String toString(){ 428 | return "min: "+ minWidth +"x"+minHeight+" ("+minInterval+") - max: " 429 | +maxWidth + "x" + maxHeight+" ("+ maxInterval+") - step: "+ 430 | stepWidth + "x" + stepHeight+ ")\n"; 431 | } 432 | } 433 | } 434 | --------------------------------------------------------------------------------