/*
* @(#)DataSource.java 1.7 02/08/21
*
* Copyright (c) 1996-2002 Sun Microsystems, Inc. All rights reserved.
*/
package com.ibm.media.protocol.ds;
import java.io.*;
import javax.media.*;
import javax.media.protocol.*;
import com.sun.media.JMFSecurityManager;
/**
* This class is a DataSource for video capture with DirectShow
*/
public class DataSource extends PushBufferDataSource {
DSSourceStream[] streams = new DSSourceStream[1];
DSSourceStream stream = null;
boolean connected = false;
boolean started = false;
static {
JMFSecurityManager.loadLibrary("jmds");
}
/**
* A no-argument constructor required by pre 1.1 implementations
* so that this class can be instantiated by
* calling <CODE>Class.newInstance</CODE>.
*
*/
public DataSource() {
super();
}
/**
* Get a string that describes the content-type of the media
* that the source is providing.
* <p>
* It is an error to call <CODE>getContentType</CODE> if the source is
* not connected.
*
* @return The name that describes the media content.
*/
public String getContentType() {
return "raw";
}
/**
* Open a connection to the source described by
* the <CODE>MediaLocator</CODE>.
* <p>
*
* The <CODE>connect</CODE> method initiates communication with the source.
*
* @exception IOException Thrown if there are IO problems
* when <CODE>connect</CODE> is called.
*/
public void connect() throws IOException {
if (connected)
return;
MediaLocator locator = getLocator();
String remainder = locator.getRemainder();
int deviceNo = -1;
if (remainder.startsWith("//")) {
remainder = remainder.substring(2);
try {
deviceNo = Integer.valueOf(remainder).intValue();
}
catch (NumberFormatException e) {
deviceNo = -1;
}
}
if (deviceNo == -1) {
System.out.println("Illegal locator, using default device");
System.out.println("Use: ds://<DeviceNumber> for specific device");
deviceNo = 0;
}
if (!buildDSGraph(deviceNo)) {
System.out.println("Error building DirectShow Filter Graph");
throw new IOException("Error building DirectShow Filter Graph");
}
stream = new DSSourceStream(); // should we have here parameters???
connected = true;
}
/**
* Build the DirectShow capture filter graph
*
* @return true if succeed, false otherwise
*/
private native boolean buildDSGraph(int deviceNo);
/**
* Close the connection to the source described by the locator.
* <p>
* The <CODE>disconnect</CODE> method frees resources used to maintain a
* connection to the source.
* If no resources are in use, <CODE>disconnect</CODE> is ignored.
* If <CODE>stop</CODE> hasn't already been called,
* calling <CODE>disconnect</CODE> implies a stop.
*
*/
public void disconnect() {
if (!connected)
return;
destroyDSGraph();
stream = null;
connected = false;
}
/**
* Destroy the DirectShow capture filter graph
*/
private native void destroyDSGraph();
/**
* Initiate data-transfer. The <CODE>start</CODE> method must be
* called before data is available.
*(You must call <CODE>connect</CODE> before calling <CODE>start</CODE>.)
*
* @exception IOException Thrown if there are IO problems with the source
* when <CODE>start</CODE> is called.
*/
public void start() throws IOException {
if (started)
return;
stream.start(); // start a thread to initiate the Processor's read() calls
if (!startDSGraph()) {
System.out.println("Error while starting DirectShow Filter Graph");
throw new IOException("Error while starting DirectShow Filter Graph");
}
started = true;
}
/**
* Start the DirectShow capture filter graph
*
* @return true if succeed, false otherwise
*/
private native boolean startDSGraph();
/**
* Stop the data-transfer.
* If the source has not been connected and started,
* <CODE>stop</CODE> does nothing.
*/
public void stop() throws IOException {
if (!started)
return;
stream.stop();
if (!stopDSGraph()) {
System.out.println("Error stopping DirectShow Filter Graph");
throw new IOException("Error stopping DirectShow Filter Graph");
}
started = false;
}
/**
* Stop the DirectShow capture filter graph
*
* @return true if succeed, false otherwise
*/
private native boolean stopDSGraph();
/**
* Get the collection of streams that this source
* manages. The collection of streams is entirely
* content dependent. The <code>ContentDescriptor</code>
* of this <CODE>DataSource</CODE> provides the only indication of
* what streams can be available on this connection.
*
* @return The collection of streams for this source.
*/
public PushBufferStream[] getStreams() {
streams[0] = stream;
return streams;
}
/**
* Get the duration of the media represented
* by this object.
* The value returned is the media's duration
* when played at the default rate.
* If the duration can't be determined (for example, the media object is presenting live
* video) <CODE>getDuration</CODE> returns <CODE>DURATION_UNKNOWN</CODE>.
*
* @return A <CODE>Time</CODE> object representing the duration or DURATION_UNKNOWN.
*/
public Time getDuration() {
return DURATION_UNKNOWN;
}
/**
* Obtain the collection of objects that
* control the object that implements this interface.
* <p>
*
* If no controls are supported, a zero length
* array is returned.
*
* @return the collection of object controls
*/
public Object[] getControls() {
return new Object[0];
}
/**
* Obtain the object that implements the specified
* <code>Class</code> or <code>Interface</code>
* The full class or interface name must be used.
* <p>
*
* If the control is not supported then <code>null</code>
* is returned.
*
* @return the object that implements the control,
* or <code>null</code>.
*/
public Object getControl(String controlType) {
return null;
}
}
|