FileDocCategorySizeDatePackage
DevicePushSourceStream.javaAPI DocJMF 2.1.1e5079Mon May 12 12:21:22 BST 2003com.ibm.media.protocol.device

DevicePushSourceStream.java

/*
 * @(#)DevicePushSourceStream.java	1.9 02/08/21
 *
 * Copyright (c) 1996-2002 Sun Microsystems, Inc.  All rights reserved.
 */

package com.ibm.media.protocol.device;

import javax.media.protocol.*;
import javax.media.Format;
import javax.media.format.*;

// public SHOULD BE REMOVED
public class DevicePushSourceStream implements PushSourceStream, Runnable {
  
    /**
     * The Handler to service data transfers to this stream
     */
    private SourceTransferHandler handler;

    /**
     * The thread which responsible on generating the transferData call
     */
    Thread triggerThread;
  
    /**
     * Indicates the stream was started
     */
    boolean started = false;
  
    static {
	com.sun.media.JMFSecurityManager.loadLibrary("jmdevice");
    }
  
    /**
     * Obtain the format that this object is set to.
     *
     * @return the current format.
     */
    public Format getFormat() {
    
	// TEMPORARY IMPLEMENTATION
	return new AudioFormat(AudioFormat.LINEAR, 22050, 16, 1);
    }
   
    /**
     * 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() {
    
	// no controls implemented
	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) {
	// no control implemented
	return null;
    }
  
    /**
     * Get the current content type for this stream.
     *
     * @return The current <CODE>ContentDescriptor</CODE> for this stream.
     */
    public ContentDescriptor getContentDescriptor() {

	// temporary implemantation
	return new 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() {
	// currently we just return false but it should be changed 
	return false;
    }

    /**
     * Read from the stream without blocking.
     * Returns -1 when the end of the media
     * is reached.
     *
     * @param buffer The buffer to read bytes into.
     * @param offset The offset into the buffer at which to begin writing data.
     * @param length The number of bytes to read.
     * @return The number of bytes read or -1
     * when the end of stream is reached.
     */
    public synchronized native int read(byte[] buffer, int offset, int length);
  
    /**
     * Determine the size of the buffer needed for the data transfer.
     * This method is provided so that a transfer handler
     * can determine how much data, at a minimum, will be
     * available to transfer from the source.
     * Overflow and data loss is likely to occur if this much
     * data isn't read at transfer time.
     *
     * @return The size of the data transfer.
     */
    public int getMinimumTransferSize() {
	/* NOT IMPLEMENTED YET */
	return 128;
    }
  
    /**
     * 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(SourceTransferHandler transferHandler) {
	handler = transferHandler;
    }

    /**
     * Runnable's method implementation
     */
    public void run() {
	while (started) {
	    handler.transferData(this);
	    while (!isBufferFilled()) {
		try {
		    synchronized(this) {
			wait();
		    }
		}
		catch (InterruptedException e) {
		    System.out.println("Exception: " + e);
		}
	    }
	}
	started = true; // this is a temporary solution for signaling the thead exit
    }

    /**
     * Starts a thread to initiate trasferData called on the Handler. 
     * The thread will wait untill the buffer sent to the device is 
     * full and than will call trasferData again
     */
    void start() {
	triggerThread = new Thread(this);
	started = true;
	triggerThread.start();
    }	

    /**
     * Stops the thread
     */
    void stop() {
	started = false;
	while (!started); // TEMPORARY SOLUTION, TO BE REPLACED
    }
   
    /**
     * Checks a the bufferFilled flag in the native code
     */
    private native boolean isBufferFilled();
  
}