FileDocCategorySizeDatePackage
V4LSourceStream.javaAPI DocJMF 2.1.1e9778Mon May 12 12:21:30 BST 2003com.sun.media.protocol.v4l

V4LSourceStream

public class V4LSourceStream extends Object implements PushBufferStream, Runnable, javax.media.control.FormatControl

Fields Summary
protected CaptureDeviceInfo
cdi
protected javax.media.control.FormatControl[]
formatControls
protected ContentDescriptor
cd
protected Format[]
supportedFormats
protected int
maxDataLength
protected byte[]
data
protected int
deviceNo
protected int
seqNo
protected VideoFormat
currentFormat
protected VideoFormat
requestedFormat
protected int
requestedPort
protected boolean
started
protected boolean
stopped
protected Thread
thread
protected float
frameRate
protected BufferTransferHandler
transferHandler
protected Control[]
controls
protected V4LCapture
capture
SystemTimeBase
systemTimeBase
Constructors Summary
public V4LSourceStream(MediaLocator locator)


    
       
	// Get the device number and preferred format from the locator
	VideoFormat locatorFormat = parseLocator(locator);
	// Make sure we can find/create a CaptureDeviceInfo object
	if (getCaptureDeviceInfo() == null)
	    throw new Error("No such capture device!");
	// Pick the default format
	requestedFormat = (VideoFormat) getSupportedFormats()[0];
	// Update the format if any changes are specified in the locator
	if (locatorFormat != null)
	    requestedFormat = (VideoFormat) locatorFormat.intersects(requestedFormat);

	// Create and open the capture device
	try {
	    capture = new V4LCapture(deviceNo);
	} catch (Throwable t) {
	    throw new Error("Couldn't initialize capture device");
	}

	// Set the port (channel)
	if (requestedPort != -1)
	    setPort(requestedPort);

	// Set the capture format. This can be changed until the start() call
	setFormat(requestedFormat);
	//handleFormatChange();
    
Methods Summary
protected CaptureDeviceInfoautoDetect(int cardNo)

	CaptureDeviceInfo cdi = null;
	try {
	    cdi = new V4LDeviceQuery(cardNo);
	    if ( cdi != null && cdi.getFormats() != null &&
		 cdi.getFormats().length > 0) {
		// Commit it to disk. Its a new device
		if (CaptureDeviceManager.addDevice(cdi)) {
		    CaptureDeviceManager.commit();
		}
	    }
	} catch (Throwable t) {
	    if (t instanceof ThreadDeath)
		throw (ThreadDeath)t;
	}
	
	return cdi;
    
synchronized voidclose()

	if (capture != null) {
	    if (started)
		start(false);
	    capture.close();
	    capture = null;
	}
    
public booleanendOfStream()

	return false;
    
public CaptureDeviceInfogetCaptureDeviceInfo()

	if (cdi == null) {
	    String url = "v4l://" + deviceNo;

	    // Check if device is registered with CaptureDeviceManager
	    Vector cdiList =
		CaptureDeviceManager.getDeviceList(new VideoFormat(null));
	    if (cdiList != null && cdiList.size() > 0) {
		for (int i = 0; i < cdiList.size(); i++) {
		    CaptureDeviceInfo tempCDI =
			(CaptureDeviceInfo) cdiList.elementAt(i);
		    if (tempCDI.getLocator().toString().equalsIgnoreCase(url)) {
			cdi = tempCDI;
			break;
		    }
		}
	    }
	    
	    // If we couldn't find it registered in CaptureDeviceManager
	    if (cdi == null) {
		cdi = autoDetect(deviceNo);
	    }
	}

	if (cdi != null) {
	    supportedFormats = cdi.getFormats();
	}
	
	return cdi;
    
public ContentDescriptorgetContentDescriptor()
SourceStream

	return cd;
    
public longgetContentLength()

	return LENGTH_UNKNOWN;
    
public java.lang.ObjectgetControl(java.lang.String controlType)

       try {
          Class  cls = Class.forName(controlType);
          Object cs[] = getControls();
          for (int i = 0; i < cs.length; i++) {
             if (cls.isInstance(cs[i]))
                return cs[i];
          }
          return null;

       } catch (Exception e) {   // no such controlType or such control
         return null;
       }
    
public java.awt.ComponentgetControlComponent()

	// TODO
	return null;
    
public java.lang.Object[]getControls()

	return controls;
    
protected intgetDeviceNo(MediaLocator locator)

	int deviceNo = 0;
	String remainder = locator.getRemainder();
	if (remainder != null && remainder.length() > 0) {
	    while (remainder.length() > 1 && remainder.charAt(0) == '/")
		remainder = remainder.substring(1);
	    try {
		Integer integer = Integer.valueOf(remainder);
		if (integer != null)
		    deviceNo = integer.intValue();
	    } catch (Throwable t) {
	    }
	}
	return deviceNo;
    
public FormatgetFormat()
PushBufferStream

	return currentFormat;
    
public javax.media.control.FormatControl[]getFormatControls()

	if (formatControls == null) {
	    formatControls = new FormatControl[1];
	    formatControls[0] = (FormatControl) this;
	}
	return formatControls;
    
public Format[]getSupportedFormats()
FormatControl

	return supportedFormats;
    
protected FormathandleFormatChange()

	VideoFormat inf = requestedFormat;
	requestedFormat = null;
	int palette = capture.formatToPalette(inf);
	float frameRate = inf.getFrameRate();
	if (frameRate < 0)
	    frameRate = 30f;
	VPicture vpict = new VPicture();
	capture.getPicture(vpict);
	vpict.palette = palette;
	vpict.depth = capture.paletteToDepth(palette);
	capture.setPicture(vpict);
	if (capture.setFormat(vpict.depth, palette,
			      inf.getSize().width,
			      inf.getSize().height,
			      frameRate) < 0) {
	    return null;
	}
	currentFormat = inf;
	return currentFormat;
    
public booleanisEnabled()

	return true;
    
protected VideoFormatparseLocator(MediaLocator loc)

	deviceNo = getDeviceNo(loc);

	// TODO : add other parameters to the locator, such as size, channel,
	//        and format
	
	return null;
    
public voidread(Buffer buffer)

	int retVal = 0;
	if (!started)
	    throw new IOException("Not started");
	maxDataLength = currentFormat.getMaxDataLength();
	Object outdata = buffer.getData();
	if (!(outdata instanceof byte[]) || ((byte[])outdata).length < maxDataLength) {
	    outdata = new byte[maxDataLength];
	    buffer.setData(outdata);
	}
	synchronized (this) {
	    int count = 0;
	    while ( (retVal = capture.readNextFrame((byte[]) outdata, 0, maxDataLength) ) < 0 && count < 20 ) {
		try {
		    Thread.sleep(10);
		} catch (InterruptedException ie) {
		}
		count++;
	    }
	    buffer.setFormat(currentFormat);
	    buffer.setSequenceNumber( seqNo );
	    buffer.setLength(maxDataLength);
	    buffer.setFlags(Buffer.FLAG_KEY_FRAME | Buffer.FLAG_SYSTEM_TIME |
			    Buffer.FLAG_LIVE_DATA);
	    buffer.setHeader( null );
	    buffer.setTimeStamp(systemTimeBase.getNanoseconds());
	    seqNo++;
	}
    
public voidrun()
Runnable

	stopped = false;
	while (started) {
	    synchronized (this) {
		while (transferHandler == null && started) {
		    try {
			wait(200);
		    } catch (InterruptedException ie) {
		    }
		} // while
	    }

	    if (started && transferHandler != null) {
		transferHandler.transferData(this);
		try {
		    Thread.currentThread().sleep( 1 );
		} catch (InterruptedException ise) {
		}
	    }
	} // while (started)
	stopped = true;
    
public voidsetEnabled(boolean value)

	// ignore
    
public FormatsetFormat(Format inf)

	if (com.sun.media.BasicPlugIn.matches(inf, getSupportedFormats()) == null)
	    return null;
	requestedFormat = (VideoFormat) inf;
	if (!started)
	    return handleFormatChange();
	return requestedFormat;
    
protected voidsetPort(java.lang.String portMatch)

	portMatch = portMatch.toLowerCase();
	VCapability vcap = new VCapability();
	capture.getCapability(vcap);
	VChannel vchan;
	// Search through all channels to find the first matching
	// channel name that contains portMatch
	for (int i = 0; i < vcap.channels; i++) {
	    vchan = new VChannel(i);
	    capture.getChannel(vchan);
	    if (vchan.name != null &&
		vchan.name.toLowerCase().indexOf(portMatch) >= 0) {
		capture.setChannel(vchan);
		return;
	    }
	}
    
protected voidsetPort(int portNo)

	// TODO
    
public voidsetTransferHandler(BufferTransferHandler transferHandler)

	synchronized (this) {
	    this.transferHandler = transferHandler;
	    notifyAll();
	}
    
voidstart(boolean started)

	synchronized ( this ) {
	    // Check if current state is same as requested state
	    if (this.started == started)
		return;
	    this.started = started;
	    if (started) {
		if (requestedFormat != null)
		    handleFormatChange();
		thread = new Thread(this);
		capture.start();
		thread.start();
	    } else {
		stopped = true;
		capture.stop();
	    }
	    notifyAll();
	}