/*
* @(#)VFWDeviceQuery.java 1.8 02/08/21
*
* Copyright (c) 1996-2002 Sun Microsystems, Inc. All rights reserved.
*/
package com.sun.media.protocol.vfw;
import javax.media.*;
import javax.media.Format;
import javax.media.format.VideoFormat;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import com.sun.media.vfw.*;
import com.sun.media.util.WindowUtil;
public class VFWDeviceQuery extends CaptureDeviceInfo {
private int capHandle;
private Vector vecFormats = null;
protected Dimension [] sizes = {
new Dimension(80, 60),
new Dimension(160, 120),
new Dimension(176, 144),
//new Dimension(240, 180),
new Dimension(320, 240),
new Dimension(352, 288),
new Dimension(640, 480),
new Dimension(768, 576)
};
protected String [] knownFourCC = {
"YUY2",
"Y411",
"YVU9",
"YV12",
"I420",
"MJPG",
"VDEC",
"VGPX",
"WINX",
"MPGI"
};
protected int [] knownBitCount = {
16, // YUY2
12, // Y411
9, // YVU9
12, // YV12
12, // I420 // YUV12
24, // MJPG compressed
16, // VDEC ???
24, // VGPX ???
24, // WINX ???
24, // MPGI ???
};
private void addFormat(Format fin) {
Enumeration enum = vecFormats.elements();
while (enum.hasMoreElements()) {
Format f = (Format) enum.nextElement();
if (f.equals(fin))
return;
}
//System.err.println("New format = " + fin);
vecFormats.addElement(fin);
}
public VFWDeviceQuery(int index) {
//System.err.println("Before creating window");
int parentWindow = VFWCapture.createWindow("Crap");
//System.err.println("After creating window");
capHandle = VFWCapture.capCreateCaptureWindow("Test",
parentWindow,
0, 0, 320, 240,
VFWCapture.getNextID());
if (capHandle == 0) {
VFWCapture.destroyWindow(parentWindow);
throw new RuntimeException("Could not create capture window");
}
if (!VFWCapture.capDriverConnect(capHandle, index)) {
VFWCapture.destroyWindow(capHandle);
VFWCapture.destroyWindow(parentWindow);
throw new RuntimeException("Unsupported device");
}
BitMapInfo bmi = new BitMapInfo();
VideoFormat vf;
vecFormats = new Vector();
// Get the default format
VFWCapture.capGetVideoFormat(capHandle, bmi);
if ( bmi.biWidth == 0 ||
bmi.biHeight == 0 ||
(bmi.biBitCount == 8 && bmi.fourcc.equalsIgnoreCase("RGB"))) {
// nothing
} else {
vf = bmi.createVideoFormat(byte[].class);
addFormat(vf);
}
// Apply and verify different RGB formats.
int i;
int bitCount;
// 16-bit RGB
BitMapInfo bmTry = new BitMapInfo("RGB", 0, 0,
1, 16, 0, 0, 0);
for (i = 0; i < sizes.length; i++) {
Dimension size = sizes[i];
bmTry.biWidth = size.width;
bmTry.biHeight = size.height;
bmTry.biSizeImage = size.width * size.height * 2;
VFWCapture.capSetVideoFormat(capHandle, bmTry);
VFWCapture.capGetVideoFormat(capHandle, bmi);
if ( bmi.biWidth == 0 ||
bmi.biHeight == 0 ) {
continue;
}
vf = bmi.createVideoFormat(byte[].class);
addFormat(vf);
}
// 24-bit RGB
bmTry = new BitMapInfo("RGB", 0, 0,
1, 24, 0, 0, 0);
for (i = 0; i < sizes.length; i++) {
Dimension size = sizes[i];
bmTry.biWidth = size.width;
bmTry.biHeight = size.height;
bmTry.biSizeImage = size.width * size.height * 3;
VFWCapture.capSetVideoFormat(capHandle, bmTry);
VFWCapture.capGetVideoFormat(capHandle, bmi);
if ( bmi.biWidth == 0 ||
bmi.biHeight == 0 ) {
continue;
}
vf = bmi.createVideoFormat(byte[].class);
addFormat(vf);
}
/*
// 32-bit RGB
bmTry = new BitMapInfo("RGB", 0, 0,
1, 32, 0, 0, 0);
for (i = 0; i < sizes.length; i++) {
Dimension size = sizes[i];
bmTry.biWidth = size.width;
bmTry.biHeight = size.height;
bmTry.biSizeImage = size.width * size.height * 4;
VFWCapture.capSetVideoFormat(capHandle, bmTry);
VFWCapture.capGetVideoFormat(capHandle, bmi);
if ( bmi.biWidth == 0 ||
bmi.biHeight == 0 ) {
continue;
}
vf = bmi.createVideoFormat(byte[].class);
addFormat(vf);
}
*/
String partName = VFWCapture.capDriverGetName(capHandle);
// Special case for VGPX
boolean hasVGPX = false;
int startCode = 0;
int endCode = knownFourCC.length;
// Special case for Color QuickCam 2
if (partName.startsWith("Color QuickCam video")) {
startCode = 6;
endCode = 7;
}
if (partName.startsWith("Logitech QuickCam")) {
startCode = 6;
endCode = 6;
}
// Apply and verify other known formats.
for (int j = startCode; j < endCode; j++) {
//System.err.println("Trying " + knownFourCC[j]);
bitCount = knownBitCount[j];
bmTry = new BitMapInfo(knownFourCC[j], 0, 0,
1, bitCount, 0, 0, 0);
for (i = 0; i < sizes.length; i++) {
Dimension size = sizes[i];
bmTry.biWidth = size.width;
bmTry.biHeight = size.height;
if (knownFourCC[j].equals("VGPX") &&
(size.width == 80 || size.width == 176 ||
size.width > 320))
continue;
bmTry.biSizeImage = size.width * size.height * bitCount / 8;
//System.err.println("Trying " + bmTry);
VFWCapture.capSetVideoFormat(capHandle, bmTry);
VFWCapture.capGetVideoFormat(capHandle, bmi);
if ( bmi.biWidth == 0 ||
bmi.biHeight == 0 ) {
continue;
}
vf = bmi.createVideoFormat(byte[].class);
if (knownFourCC[j].equals("VGPX"))
hasVGPX = true;
addFormat(vf);
}
if (hasVGPX)
break;
}
String driverVerson = VFWCapture.capDriverGetVersion(capHandle);
VFWCapture.capDriverDisconnect(capHandle);
VFWCapture.destroyWindow(capHandle);
VFWCapture.destroyWindow(parentWindow);
//[This check doesn't seem to work. Some good devices also return a null
if (/*partName != null && !partName.equals("null")*/ true) {
name = "vfw:" + partName + ":" + index;
String strLocator = "vfw://" + index;
//System.err.println("Registering Device " + name);
//System.err.println("Device URL = " + locator);
formats = new Format[vecFormats.size()];
Enumeration enum = vecFormats.elements();
i = 0;
while (enum.hasMoreElements()) {
Format f = (Format) enum.nextElement();
formats[i++] = f;
}
locator = new MediaLocator(strLocator);
} else {
throw new RuntimeException("Unsupported device");
}
}
}
|