/* * @(#)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(); }