SunVideoSourceStreampublic class SunVideoSourceStream extends BasicSourceStream implements PushBufferStream, OwnedSourceStream for the DataSource
The SourceStream can be accessed with the URL sunvideo:
The URL has been extended to allow selecting some of the options:
sunvideo://card/port/compression/size where
card = the sunvideo card to use (default 0) when multiple
cards are installed.
port = port to use (default 1), s-vhs, 1, or 2.
compression = rgb or jpeg (default jpeg).
size = 1, 1/2, or 1/4 (default 1/2). Actual frame size
depends on whether the camera is NTSC or PAL. |
Fields Summary |
---|
private DataSource | dataSource | private MediaLocator | locator | int | maxDataSize | BufferTransferHandler | transferHandler | private byte[] | data | private int | length | private long | nextSequence | long | timeStamp | XILCapture | svCap | SystemTimeBase | systemTimeBase | private VideoFormat | capFormat | private static Format[] | supported | private static final boolean | CONTROL_PANEL_HACK | private Frame | controlFrame | private static Integer | SunVideoLock | Integer | readLock | private boolean | started | private boolean | connected | private boolean | connectedOK | private boolean | inUse | private int | cardNo | private static String[] | VALID_PORTS | private static final int | DEFAULT_PORT | private int | portNo | private static String[] | VALID_COMPRESS | private static String[] | VIDEO_COMPRESS | private static final int | DEFAULT_COMPRESS | private static final int | RGB_COMPRESS | private int | compressNo | private static String[] | VALID_SIZES | private static Dimension[] | DEFAULT_DIMENSIONS | private static float[] | VALID_SIZES_FLOAT | private static int[] | VALID_SCALE | private static final int | DEFAULT_SIZE | private static float | SIZE_GRANULARITY | private int | sizeNo | private static final int | DEFAULT_RATE | private int | rateNo | private static final int | DEFAULT_QUALITY | private int | qualityNo | private LocalPortControl | portControl | private RateControl | rateControl | private LocalQualityControl | qualityControl | private LocalFormatControl | formatControl | private float | preferredFrameRate | private PushThread | pt | long | ptDelay | private static JMFSecurity | jmfSecurity | private static boolean | securityPrivelege | private Method[] | mSecurity | private Class[] | clSecurity | private Object[] | argsSecurity |
Constructors Summary |
---|
public SunVideoSourceStream(DataSource ds)
try {
jmfSecurity = JMFSecurityManager.getJMFSecurity();
securityPrivelege = true;
} catch (SecurityException e) {
}
supported = new javax.media.Format[] {
// NTSC
// JPEG formats
new javax.media.format.VideoFormat(
javax.media.format.VideoFormat.JPEG,
new Dimension(320, 240),
javax.media.format.VideoFormat.NOT_SPECIFIED,
Format.byteArray,
javax.media.format.VideoFormat.NOT_SPECIFIED),
new javax.media.format.VideoFormat(
javax.media.format.VideoFormat.JPEG,
new Dimension(160, 120),
javax.media.format.VideoFormat.NOT_SPECIFIED,
Format.byteArray,
javax.media.format.VideoFormat.NOT_SPECIFIED),
// RGB formats
new javax.media.format.VideoFormat(
javax.media.format.VideoFormat.RGB,
new Dimension(640, 480),
javax.media.format.VideoFormat.NOT_SPECIFIED,
Format.byteArray,
javax.media.format.VideoFormat.NOT_SPECIFIED),
new javax.media.format.VideoFormat(
javax.media.format.VideoFormat.RGB,
new Dimension(320, 240),
javax.media.format.VideoFormat.NOT_SPECIFIED,
Format.byteArray,
javax.media.format.VideoFormat.NOT_SPECIFIED),
new javax.media.format.VideoFormat(
javax.media.format.VideoFormat.RGB,
new Dimension(160, 120),
javax.media.format.VideoFormat.NOT_SPECIFIED,
Format.byteArray,
javax.media.format.VideoFormat.NOT_SPECIFIED),
// PAL
// JPEG formats
new javax.media.format.VideoFormat(
javax.media.format.VideoFormat.JPEG,
new Dimension(384, 288),
javax.media.format.VideoFormat.NOT_SPECIFIED,
Format.byteArray,
javax.media.format.VideoFormat.NOT_SPECIFIED),
new javax.media.format.VideoFormat(
javax.media.format.VideoFormat.JPEG,
new Dimension(192, 144),
javax.media.format.VideoFormat.NOT_SPECIFIED,
Format.byteArray,
javax.media.format.VideoFormat.NOT_SPECIFIED),
// RGB formats
new javax.media.format.VideoFormat(
javax.media.format.VideoFormat.RGB,
new Dimension(768, 576),
javax.media.format.VideoFormat.NOT_SPECIFIED,
Format.byteArray,
javax.media.format.VideoFormat.NOT_SPECIFIED),
new javax.media.format.VideoFormat(
javax.media.format.VideoFormat.RGB,
new Dimension(384, 288),
javax.media.format.VideoFormat.NOT_SPECIFIED,
Format.byteArray,
javax.media.format.VideoFormat.NOT_SPECIFIED),
new javax.media.format.VideoFormat(
javax.media.format.VideoFormat.RGB,
new Dimension(192, 144),
javax.media.format.VideoFormat.NOT_SPECIFIED,
Format.byteArray,
javax.media.format.VideoFormat.NOT_SPECIFIED),
};
super(new ContentDescriptor(ContentDescriptor.RAW),
LENGTH_UNKNOWN);
this.dataSource = ds;
this.locator = ds.getLocator();
cardNo = 0;
String remainder = locator.getRemainder();
if (remainder != null && remainder.length() > 0) {
while (remainder.length() > 1 && remainder.charAt(0) == '/")
remainder = remainder.substring(1);
String cardStr, portStr, compStr, sizeStr;
portStr = null; // assume no port specified
compStr = null; // assume no compress specified
sizeStr = null; // assume no size specified
// Now see if there's a port specified.
int off = remainder.indexOf('/");
if (off == -1) {
cardStr = remainder;
} else {
cardStr = remainder.substring(0, off);
remainder = remainder.substring(off + 1);
// Now see if there's a compression specified
off = remainder.indexOf('/");
if (off == -1) {
portStr = remainder;
} else {
portStr = remainder.substring(0, off);
remainder = remainder.substring(off + 1);
// Now see if there's a size specified
off = remainder.indexOf('/");
if (off == -1) {
compStr = remainder;
} else {
compStr = remainder.substring(0, off);
sizeStr = remainder.substring(off + 1);
}
}
}
try {
Integer integer = Integer.valueOf(cardStr);
if (integer != null) {
cardNo = integer.intValue();
}
} catch (Throwable t) {
}
if (portStr != null && portStr.length() > 0) {
for (int i = 0; i < VALID_PORTS.length; i++) {
if (VALID_PORTS[i].equalsIgnoreCase(portStr)) {
portNo = i;
}
}
}
if (compStr != null && compStr.length() > 0) {
for (int i = 0; i < VALID_COMPRESS.length; i++) {
if (VALID_COMPRESS[i].equalsIgnoreCase(compStr)) {
compressNo = i;
}
}
}
if (sizeStr != null && sizeStr.length() > 0) {
for (int i = 0; i < VALID_SIZES.length; i++) {
if (VALID_SIZES[i].equalsIgnoreCase(sizeStr)) {
sizeNo = i;
}
}
}
}
capFormat = new javax.media.format.VideoFormat(
VIDEO_COMPRESS[compressNo],
DEFAULT_DIMENSIONS[sizeNo],
javax.media.format.VideoFormat.NOT_SPECIFIED,
Format.byteArray,
getRate());
svCap = new XILCapture(this);
portControl = new LocalPortControl(this, VALID_PORTS, portNo);
rateControl = new RateControl(this, (float)DEFAULT_RATE, 1f, 30f);
qualityControl = new LocalQualityControl(this,
((float)DEFAULT_QUALITY/100f),
0.01f, 0.62f);
formatControl = new LocalFormatControl(this);
controls = new Object[4];
controls[0] = portControl;
controls[1] = rateControl;
controls[2] = qualityControl;
controls[3] = formatControl;
|
Methods Summary |
---|
public void | connect()
synchronized (SunVideoLock) {
if (inUse) {
throw new IOException("Capture device in use");
} else
inUse = true;
connected = false;
if (!doConnect()) {
inUse = false;
throw new IOException("Could not connect to capture device");
}
connected = true;
}
// Following only needed while the control frame hack is present...
if (CONTROL_PANEL_HACK)
doControlPanelHack();
// Preceding only needed while the control frame hack is present...
| synchronized void | disconnect()
// System.err.println("SunVideoSourceStream.disconnect");
if (started) {
try {
stop();
} catch (IOException ioe) {
}
}
synchronized (SunVideoLock) {
connected = false;
svCap.disconnect();
pt = null;
inUse = false;
}
// Following only needed while the control frame hack is present...
if(CONTROL_PANEL_HACK && controlFrame != null) {
controlFrame.setVisible(false);
controlFrame.removeAll();
controlFrame.dispose();
controlFrame = null;
}
// Preceding only needed while the control frame hack is present...
| private boolean | doConnect()
// System.err.println("SunVideoSourceStream.doConnect");
if (!svCap.connect(cardNo, portNo))
return false;
setSize(sizeNo); // set the scale
setCompress(compressNo); // set the compression
data = new byte[maxDataSize]; // prime the data field for push
nextSequence = 1; // reset in case it's a reconnect
return true;
| private void | doControlPanelHack()
if (controlFrame != null) {
controlFrame.setVisible(true);
return;
}
controlFrame = new Frame("SunVideo Controls");
controlFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
controlFrame.setVisible(false);
}
});
controlFrame.setLayout(new BorderLayout());
Panel p = new Panel();
p.setLayout(new FlowLayout(FlowLayout.LEFT, 1, 1));
// p.add(new LabelComponent("Port"));
p.add(portControl.getControlComponent());
// p.add(new LabelComponent("Format"));
p.add(formatControl.getControlComponent());
controlFrame.add(p, "North");
p = new Panel();
p.setLayout(new FlowLayout(FlowLayout.LEFT, 1, 1));
p.add(rateControl.getControlComponent());
p.add(qualityControl.getControlComponent());
controlFrame.add(p, "South");
controlFrame.pack();
controlFrame.setVisible(true);
| public void | finalize()
if (connected)
disconnect();
| public javax.media.CaptureDeviceInfo | getCaptureDeviceInfo()
// TODO - more useful descriptor of device
return new CaptureDeviceInfo("SunVideo", locator, supported);
| boolean | getConnected()
return connected;
| byte[] | getData()
return data;
| public java.lang.Object | getDataType()
return Format.byteArray;
| public javax.media.Format | getFormat()
// System.err.println("SunVideoSourceStream.getFormat");
return capFormat;
| public java.lang.Object | getOwner()Owned
return dataSource;
| float | getQuality()
return ((float) qualityNo / 100f);
| float | getRate()
if (rateNo == 30)
return 29.97f; // NTSC standard broadcast frame rate
return (float) rateNo;
| int | getSize()
return sizeNo;
| float | getSizeFloat()
return VALID_SIZES_FLOAT[sizeNo];
| float[] | getSizesFloat()
return VALID_SIZES_FLOAT;
| boolean | getStarted()
return started;
| public javax.media.Format[] | getSupportedFormats()
// System.err.println("SunVideoSourceStream.getSupportedFormats");
return supported;
| void | pushData(int length)
this.length = length;
if (transferHandler != null)
transferHandler.transferData(this);
| public void | read(javax.media.Buffer buffer)
// System.err.println("SunVideoSourceStream.read");
if (!started) {
buffer.setDiscard(true);
length = 0;
return;
}
synchronized (readLock) {
if (length > 0) {
byte [] outgoingData = data;
Object incomingData = buffer.getData();
if (incomingData instanceof byte[] &&
((byte[])incomingData).length >= maxDataSize) {
data = (byte []) incomingData;
} else {
data = new byte[maxDataSize];
}
buffer.setOffset(0);
buffer.setData(outgoingData);
buffer.setLength(length);
buffer.setDiscard(false);
buffer.setSequenceNumber(nextSequence++);
buffer.setTimeStamp(timeStamp);
buffer.setFlags(buffer.getFlags() |
buffer.FLAG_SYSTEM_TIME |
buffer.FLAG_KEY_FRAME |
buffer.FLAG_LIVE_DATA);
buffer.setFormat(capFormat);
} else
buffer.setDiscard(true);
length = 0;
}
| private void | setCompress(java.lang.String compress)
if (compress != null && compress.length() > 0) {
for (int i = 0; i < VALID_COMPRESS.length; i++) {
if (VALID_COMPRESS[i].equalsIgnoreCase(compress)) {
compressNo = i;
if (connected)
setCompress(compressNo);
}
}
}
| private void | setCompress(int compress)
compressNo = compress;
svCap.setCompress(VALID_COMPRESS[compressNo]);
if (compress == RGB_COMPRESS) {
qualityControl.setEnabled(false);
} else {
qualityControl.setEnabled(true);
}
| void | setData(byte[] buf)
data = buf;
| public javax.media.Format | setFormat(javax.media.Format fmt)
if (fmt.equals(capFormat))
return capFormat;
//System.err.println("SunVideoSourceStream.setFormat() format: " + fmt);
javax.media.Format f = null;
for (int i = 0; i < supported.length; i++) {
if (fmt.matches(supported[i]) &&
(f = fmt.intersects(supported[i])) != null) {
break;
}
}
if (f != null) {
VideoFormat format = (javax.media.format.VideoFormat)f;
if (format.getEncoding().equals(format.JPEG)) {
setCompress("Jpeg");
} else {
setCompress("RGB");
}
if (format.getFrameRate() !=
javax.media.format.VideoFormat.NOT_SPECIFIED) {
// rateControl will call back to setRate
rateControl.setFrameRate(format.getFrameRate());
}
setSize(format.getSize());
if (!connected) {
capFormat = format;
}
}
return capFormat;
| public void | setJpegFormat(int inWidth, int inHeight, int outWidth, int outHeight, int quality)
if (inWidth <= 0) inWidth = 640; // default to NTSC
if (inHeight <= 0) inHeight = 480; // default to NTSC
if (outWidth <= 0) outWidth = inWidth / VALID_SCALE[sizeNo];
if (outHeight <= 0) outHeight = inHeight / VALID_SCALE[sizeNo];
Dimension dim = new java.awt.Dimension(outWidth, outHeight);
if (quality > 60)
maxDataSize = 3 * outWidth * outHeight;
else
maxDataSize = 2 * outWidth * outHeight;
capFormat = new JPEGFormat(dim, maxDataSize, Format.byteArray,
getRate(), qualityNo, JPEGFormat.NOT_SPECIFIED);
formatControl.setCurrentFormat(capFormat);
| public void | setMpegFormat(int inWidth, int inHeight, int outWidth, int outHeight, int quality)
if (inWidth <= 0) inWidth = 640; // default to NTSC
if (inHeight <= 0) inHeight = 480; // default to NTSC
if (outWidth <= 0) outWidth = inWidth / VALID_SCALE[sizeNo];
if (outHeight <= 0) outHeight = inHeight / VALID_SCALE[sizeNo];
Dimension dim = new java.awt.Dimension(outWidth, outHeight);
if (quality > 60)
maxDataSize = 3 * outWidth * outHeight;
else
maxDataSize = 2 * outWidth * outHeight;
capFormat = new VideoFormat(VideoFormat.MPEG, dim,
maxDataSize, Format.byteArray,
getRate()); // frame rate
formatControl.setCurrentFormat(capFormat);
| private void | setPort(int port)
portNo = port;
svCap.setPort(portNo);
| void | setQuality(float quality)
qualityNo = (int) ((quality * 100f) + 0.5f);
svCap.setQuality(qualityNo);
if ((capFormat != null) && (capFormat instanceof JPEGFormat)) {
capFormat = new JPEGFormat(
(capFormat == null ? null : capFormat.getSize()),
maxDataSize, Format.byteArray, getRate(),
qualityNo, JPEGFormat.NOT_SPECIFIED);
}
| public void | setRGBFormat(int inWidth, int inHeight, int outWidth, int outHeight, int scanLine)
if (inWidth <= 0) inWidth = 640; // default to NTSC
if (inHeight <= 0) inHeight = 480; // default to NTSC
if (outWidth <= 0) outWidth = inWidth / VALID_SCALE[sizeNo];
if (outHeight <= 0) outHeight = inHeight / VALID_SCALE[sizeNo];
Dimension dim = new java.awt.Dimension(outWidth, outHeight);
// media engine doesn't like NOT_SPECIFIED
if (scanLine == Format.NOT_SPECIFIED)
scanLine = 3 * outWidth;
maxDataSize = scanLine * outHeight;
capFormat = new RGBFormat(dim, maxDataSize, Format.byteArray,
getRate(), // frame rate
24,
3, 2, 1, 3, scanLine,
Format.FALSE, // flipped
Format.NOT_SPECIFIED); // endian
formatControl.setCurrentFormat(capFormat);
| void | setRate(float rate)
rateNo = (int) (rate + 0.5);
if (rateNo <= 0)
rateNo = 1;
ptDelay = 1000 / rateNo;
//System.err.println("SunVideoSourceStream.setRate() rate: " + rateNo);
// Adjust frame rate in format
if (capFormat != null) {
if (VideoFormat.JPEG.equals(capFormat.getEncoding())) {
capFormat = new JPEGFormat(capFormat.getSize(),
maxDataSize, Format.byteArray, getRate(),
qualityNo, JPEGFormat.NOT_SPECIFIED);
} else if (VideoFormat.RGB.equals(capFormat.getEncoding())) {
capFormat = new RGBFormat(capFormat.getSize(),
maxDataSize, Format.byteArray,
getRate(), // frame rate
24,
3, 2, 1, 3,
((RGBFormat)capFormat).getLineStride(),
Format.FALSE, // flipped
Format.NOT_SPECIFIED); // endian
}else if (VideoFormat.MPEG.equals(capFormat.getEncoding())) {
capFormat = new VideoFormat(VideoFormat.MPEG,
capFormat.getSize(),
maxDataSize, Format.byteArray,
getRate()); // frame rate
}
formatControl.setCurrentFormat(capFormat);
}
| void | setSize(java.awt.Dimension size)
int scale = 1;
// Handle both NTSC and PAL sizes
if (size.width > 384)
scale = 1;
else if (size.width >= 320)
scale = 2;
else
scale = 4;
for (int i = 0; i < VALID_SIZES.length; i++) {
if (VALID_SCALE[i] == scale) {
sizeNo = i;
if (connected)
setSize(sizeNo);
}
}
| void | setSize(int size)
sizeNo = size;
svCap.setScale(VALID_SCALE[sizeNo]);
| void | setSize(float size)
if (size > VALID_SIZES_FLOAT[0]) {
sizeNo = 0;
} else {
for (int i = 1; i < VALID_SIZES_FLOAT.length; i++) {
sizeNo = i;
if (size > VALID_SIZES_FLOAT[i]) {
// Allow for the cases where size is not an exact match
if ((VALID_SIZES_FLOAT[i - 1] - size) <
(size - VALID_SIZES_FLOAT[i])) {
sizeNo = i - 1;
break;
}
break;
}
}
}
svCap.setScale(VALID_SCALE[sizeNo]);
| public void | setTransferHandler(javax.media.protocol.BufferTransferHandler th)
transferHandler = th;
| void | start()
// System.err.println("SunVideoSourceStream.start");
if (started)
return;
if (!svCap.start()) {
// System.err.println("SunVideoSourceStream.start failed");
throw (new IOException("SunVideoStart failed"));
}
synchronized (this) {
started = true;
// Start the video call back polling thread
if (pt == null) {
if ( /*securityPrivelege && */ (jmfSecurity != null) ) {
String permission = null;
try {
if (jmfSecurity.getName().startsWith("jmf-security")) {
permission = "thread";
jmfSecurity.requestPermission(mSecurity, clSecurity, argsSecurity,
JMFSecurity.THREAD);
mSecurity[0].invoke(clSecurity[0], argsSecurity[0]);
permission = "thread group";
jmfSecurity.requestPermission(mSecurity, clSecurity, argsSecurity,
JMFSecurity.THREAD_GROUP);
mSecurity[0].invoke(clSecurity[0], argsSecurity[0]);
} else if (jmfSecurity.getName().startsWith("internet")) {
PolicyEngine.checkPermission(PermissionID.THREAD);
PolicyEngine.assertPermission(PermissionID.THREAD);
}
} catch (Throwable e) {
if (JMFSecurityManager.DEBUG) {
System.err.println( "Unable to get " + permission +
" privilege " + e);
}
securityPrivelege = false;
// TODO: Do the right thing if permissions cannot be obtained.
// User should be notified via an event
}
}
if ( (jmfSecurity != null) && (jmfSecurity.getName().startsWith("jdk12"))) {
try {
Constructor cons = jdk12CreateThreadAction.cons;
pt = (PushThread) jdk12.doPrivM.invoke(
jdk12.ac,
new Object[] {
cons.newInstance(
new Object[] {
PushThread.class,
this
})});
} catch (Exception e) {
System.err.println("SunVideoSourceStream: exception when creating thread");
}
} else {
pt = new PushThread(this);
}
if (pt != null) {
pt.start();
}
}
if (formatControl != null) formatControl.getControlComponent().
setEnabled(false);
}
| void | stop()
// System.err.println("SunVideoSourceStream.stop");
started = false;
svCap.stop();
if (portControl != null) portControl.setEnabled(true);
if (formatControl != null) formatControl.getControlComponent().
setEnabled(true);
| public boolean | willReadBlock()
return true;
|
|