/*
* @(#)DSSourceStream.java 1.10 02/08/21
*
* Copyright (c) 1996-2002 Sun Microsystems, Inc. All rights reserved.
*/
package com.ibm.media.protocol.ds;
import java.io.*;
import java.awt.*;
import javax.media.*;
import javax.media.protocol.*;
import javax.media.format.*;
import javax.media.format.*;
import com.sun.media.vfw.*;
public class DSSourceStream implements PushBufferStream, Runnable {
private BufferTransferHandler transferHandler;
private Thread triggerThread;
private boolean started = false;
private VideoFormat format = null;
/**
* Get the current content type for this stream.
*
* @return The current <CODE>ContentDescriptor</CODE> for this stream.
*/
public ContentDescriptor getContentDescriptor() {
return new ContentDescriptor(ContentDescriptor.RAW);
}
/**
* Get the size, in bytes, of the content on this stream.
* LENGTH_UNKNOWN is returned if the length is not known.
*
* @return The content length in bytes.
*/
public long getContentLength() {
return LENGTH_UNKNOWN;
}
/**
* Find out if the end of the stream has been reached.
*
* @return Returns <CODE>true</CODE> if there is no more data.
*/
public boolean endOfStream() {
return false;
}
/**
* Get the format tupe of the data that this source stream provides.
* @return A <CODE>Format</CODE> object that describes the data in this stream.
*/
public Format getFormat() {
if (format == null) {
BitMapInfo bmi = new BitMapInfo();
getVideoFormat(bmi);
float frameRate = getFrameRate();
Format directShowFormat = bmi.createVideoFormat(Format.byteArray,
frameRate);
if (directShowFormat instanceof VideoFormat)
format = (VideoFormat)directShowFormat;
else
return new Format("DirectShowUnknown");
}
return format;
}
/**
* Fill the BitMapInfo object
*/
private native void getVideoFormat(BitMapInfo bmi);
/**
* Get the DirectShow reported frame rate
*/
private native float getFrameRate();
/**
* Read from the stream without blocking.
* @throws IOException Thrown if an error occurs while reading
*
*/
public void read(Buffer buffer) throws IOException {
// System.out.println("read");
Object data = buffer.getData();
int length = format.getMaxDataLength();
if (data == null || !(data instanceof byte[]) || ((byte[])data).length != length)
data = new byte[length];
buffer.setFormat(format);
setBuffer((byte[])data, buffer.getOffset());
try {
while (!isFilled())
Thread.sleep(50);
}
catch (InterruptedException e) {
System.out.println("Exception: " + e);
}
buffer.setData(data);
buffer.setOffset(0);
buffer.setLength(length);
buffer.setTimeStamp(Buffer.TIME_UNKNOWN);
}
/**
* Sets a buffer
*/
private native void setBuffer(byte[] data, int offset);
/**
* Checks if buffer was filled with data
*/
private native boolean isFilled();
/**
* Register an object to service data transfers to this stream.
* <p>
* If a handler is already registered when
* <CODE>setTransferHandler</CODE> is called,
* the handler is replaced;
* there can only be one handler at a time.
*
* @param transferHandler The handler to transfer data to.
*/
public void setTransferHandler(BufferTransferHandler transferHandler) {
this.transferHandler = transferHandler;
}
/**
* 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;
}
/**
* Start a thread to generate the transferData calls
*/
void start() {
if (started)
return;
triggerThread = new Thread(this);
started = true;
triggerThread.start();
}
/**
* Stops the triggerThread
*/
void stop() {
if (!started)
return;
synchronized(this) {
started = false;
try {
wait(); // wait till the triggerThread ended
}
catch (InterruptedException e) {
System.out.println("Exception: " + e);
}
}
}
/**
* Runnable implementation
*/
public void run() {
while (started) {
transferHandler.transferData(this);
/* WE ASSUME transferData IS A BLOCKING CALL - THIS MAY NOT BE THE
CASE FOR DIFFERENT IMPLEMENTATIONS OF Processors */
}
synchronized(this) {
notify(); // notify the stop method that the triggerThread has finished
}
}
}
|