FileDocCategorySizeDatePackage
RawBufferMux.javaAPI DocJMF 2.1.1e24883Mon May 12 12:20:58 BST 2003com.sun.media.multiplexer

RawBufferMux

public class RawBufferMux extends BasicPlugIn implements Multiplexer, Clock
This raw mux doesn't impose any sync on the output. It pushes out data in the order that they arrived.

Fields Summary
protected ContentDescriptor[]
supported
protected ContentDescriptor
contentDesc
protected RawBufferDataSource
source
protected RawBufferSourceStream[]
streams
protected BasicClock
clock
protected RawMuxTimeBase
timeBase
protected long[]
mediaTime
protected int
masterTrackID
boolean
sourceDisconnected
boolean
allowDrop
boolean
hasRead
private static JMFSecurity
jmfSecurity
private static boolean
securityPrivelege
private Method[]
m
private Class[]
cl
private Object[]
args
protected int
numTracks
protected Format[]
trackFormats
protected MonitorAdapter[]
mc
static AudioFormat
mpegAudio
Object
timeSetSync
boolean
started
long
systemStartTime
long
mediaStartTime
Constructors Summary
public RawBufferMux()


     
	try {
	    jmfSecurity = JMFSecurityManager.getJMFSecurity();
	    securityPrivelege = true;
	} catch (SecurityException e) {
	}
    
	supported = new ContentDescriptor[1];
	supported[0] = new ContentDescriptor(ContentDescriptor.RAW);
	timeBase = new RawMuxTimeBase();
	clock = new BasicClock();
	try {
	    clock.setTimeBase(timeBase);
	} catch (Exception e) {}
    
Methods Summary
public voidclose()
Closes the plug-in component and releases resources. No more data will be accepted by the plug-in after a call to this method. The plug-in can be reinstated after being closed by calling open.

	// stop() and disconnect() datasource and set it to null
	if (source != null){
	    try{
		source.stop();
		source.disconnect();
	    }catch (IOException e){
	    }
	    source = null;
	}

	for (int i = 0; i < mc.length; i++) {
	    if (mc[i] != null)
		mc[i].close();
	}
    
public javax.media.protocol.DataSourcegetDataOutput()
Get the output DataSource from this multiplexer. The DataSource returned can be a push or pull datasource. i.e. a Push[Pull]DataSource or Push[Pull]BufferDataSource.
The datasource must be returned in the connected state.

return
the output DataSource

	return source;
    
public longgetMediaNanoseconds()

	return clock.getMediaNanoseconds();
    
public javax.media.TimegetMediaTime()

	return clock.getMediaTime();
	
    
public java.lang.StringgetName()
Returns a descriptive name for the plug-in. This is a user readable string.

	return "Raw Buffer Multiplexer";
    
public floatgetRate()

	return clock.getRate();
    
public javax.media.TimegetStopTime()

	return clock.getStopTime();
    
public javax.media.Format[]getSupportedInputFormats()

	return new Format[] { new AudioFormat(null),
				  new VideoFormat(null) };
    
public javax.media.protocol.ContentDescriptor[]getSupportedOutputContentDescriptors(javax.media.Format[] fmt)
Lists the possible output contentdescriptors of the processed data. If input is non-null, then it lists the possible output contentdescriptors given that the input data are of the formats specified by inputs. If inputs is null, then it lists all possible output content descriptors that this plug-in advertises.

	// we support a raw format, so we dont really need to check the input
	// formats here as we are just going to pass the stream on
	// without looking at the format. 
	return supported;
    
public javax.media.TimegetSyncTime()

	return clock.getSyncTime();
	
    
public javax.media.TimeBasegetTimeBase()

	return clock.getTimeBase();
    
public booleaninitializeTracks(javax.media.Format[] trackFormats)
Initialize the tracks in the multiplexer with formats given in an array of track formats. The indexes used in the format array are used subsequently as keys to identify each individual track in the process method. This methods should be called only once. A java.lang.Error is thrown if it's called more than once.

param
trackFormats an array for formats specifying the formats for each track in the multiplexer.
return
false if one or more of the input formats are not supported.

	if( source.getStreams() != null)
	    throw new java.lang.Error("initializeTracks has been called previously. ");
	source.initialize(trackFormats);
	streams = (RawBufferSourceStream[])source.getStreams();
	// we support any input format, so always return true
	return true;
    
public javax.media.TimemapToTimeBase(javax.media.Time t)

	return clock.mapToTimeBase(t);
    
public voidopen()
Opens the plug-in software or hardware component and acquires necessary resources. If all the needed resources could not be acquired, it throws a ResourceUnavailableException. Data should not be passed into the plug-in without first calling this method.

	// the datasource must be created in
	// setContentDescriptor & streams created in
	// initializeTracks(). Make sure the source and streams were
	// created and connect the source.
	initializeTracks(trackFormats);
	
	if ((source == null) || (source.getStreams() == null))
	    throw new ResourceUnavailableException("DataSource and SourceStreams were not created succesfully.");
	try{
	    source.connect();
	}catch (IOException e){
	    throw new ResourceUnavailableException(e.getMessage());
	}

	int len = 0;
	int i;

	mediaTime = new long[trackFormats.length];
	mc = new MonitorAdapter[trackFormats.length];

	for (i = 0; i < trackFormats.length; i++) {
	    mediaTime[i] = 0;
	    if (trackFormats[i] instanceof VideoFormat ||
		 trackFormats[i] instanceof AudioFormat) {
		mc[i] = new MonitorAdapter(trackFormats[i], this);
		if (mc[i] != null)
		    len++;
	    }
	}

	int j = 0;
	controls = new Control[len];
	for (i = 0; i < mc.length; i++) {
	    if (mc[i] != null)
	        controls[j++] = mc[i];
	}
    
public intprocess(javax.media.Buffer buffer, int trackID)
Process the buffer and multiplex it with data from other tracks. The multiplexed output is sent to the output DataSource.

param
buffer the input buffer
param
trackID the index identifying the track where the input buffer belongs.
return
BUFFER_PROCESSED_OK if the processing is successful. Other possible return codes are defined in PlugIn.
see
PlugIn


	// If the processor starts out having RTP times, before the
	// data comes out of this processor, we should reset the
	// RTP flag and sets it to RELATIVE time.  Otherwise, the
	// next guy in the processing chain may compute the time
	// incorrectly.
	if ((buffer.getFlags() & Buffer.FLAG_RTP_TIME) != 0) {
	    buffer.setFlags((buffer.getFlags() & ~Buffer.FLAG_RTP_TIME) |
				Buffer.FLAG_RELATIVE_TIME);
	}

	// If the monitor is enabled, we'll send the data to the monitor.
	if (mc[trackID] != null && mc[trackID].isEnabled())
	    mc[trackID].process(buffer);

	if ((streams == null) || (buffer == null) || (trackID >=
						      streams.length)){
	    return PlugIn.BUFFER_PROCESSED_FAILED;
	}

	updateTime(buffer, trackID);

	return streams[trackID].process(buffer);
    
public voidreset()
Resets the state of the plug-in. Typically at end of media or when media is repositioned.

	for (int i = 0; i < streams.length; i++) {
	    streams[i].reset();
	    if (mc[i] != null)
		mc[i].reset();
	}
    
public javax.media.protocol.ContentDescriptorsetContentDescriptor(javax.media.protocol.ContentDescriptor outputContentDescriptor)
Set the output content-type.

param
outputContentDescriptor the content-type of the output.
exception
UnsupportedFormatException if the outputContentDescriptor cannot be supported by the Multiple xer.
exception
FormatChangeException if the Multiplexer does not support format changes after it has been set.

	    // we support changes in contentdescriptor after it has
	    // been set, so no need to check to see if its set and no
	    // need to return FormatChangeException

	    if (matches(outputContentDescriptor, supported) == null)
		return null;

	    // create the datasource and set its output
	    // contentdescriptor
	    contentDesc = outputContentDescriptor;
	    source = new RawBufferDataSource();

	    return contentDesc;
    
public javax.media.FormatsetInputFormat(javax.media.Format input, int trackID)

	if (trackID < numTracks)
	    trackFormats[trackID] = input;
	for (int i = 0; i < numTracks; i++)
	    if (trackFormats[i] == null)
		return input;
	// all formats are set
	//initializeTracks(trackFormats);
	return input;
    
public voidsetMediaTime(javax.media.Time now)

	synchronized (timeSetSync) {
	    clock.setMediaTime(now);
	    for (int i = 0; i < mediaTime.length; i++)
		mediaTime[i] = now.getNanoseconds();
	    timeBase.update();
	    systemStartTime = System.currentTimeMillis();
	    mediaStartTime = now.getNanoseconds() / 1000000;
	}
    
public intsetNumTracks(int nTracks)

	numTracks = nTracks;
	trackFormats = new Format[nTracks];
	for (int i = 0; i < nTracks; i++)
	    trackFormats[i] = null;
	return nTracks;
    
public floatsetRate(float factor)

	if (factor == clock.getRate())
	    return factor;
	return clock.setRate(1.0f);
	
    
public voidsetStopTime(javax.media.Time stopTime)

	clock.setStopTime(stopTime);
    
public voidsetTimeBase(javax.media.TimeBase master)

    
          
	if (master != timeBase)
	    throw new IncompatibleTimeBaseException();
    
public voidstop()

	synchronized (timeSetSync){
	    if (!started) return;
	    started = false;
	    clock.stop();
	    timeBase.mediaStopped();
	}
    
public voidsyncStart(javax.media.Time at)


	synchronized (timeSetSync){
	    if (started) return;
	    started = true;
	    clock.syncStart(at);
	    timeBase.mediaStarted();
	    systemStartTime = System.currentTimeMillis();
	    mediaStartTime = getMediaNanoseconds() / 1000000;
	}
    
protected voidupdateTime(javax.media.Buffer buf, int trackID)
Update the media time per track.


	if (buf.getFormat() instanceof AudioFormat) {

	    if (mpegAudio.matches(buf.getFormat())) {
		if (buf.getTimeStamp() < 0) {
		    if (systemStartTime >= 0)
			mediaTime[trackID] = (mediaStartTime + 
				System.currentTimeMillis() - systemStartTime) 
				* 1000000;
		} else
		    mediaTime[trackID] = buf.getTimeStamp();
	    } else {
		// If it's audio data and the time stamp is undefined,
		// we'll compute from the audio duration.
		long t = ((AudioFormat)buf.getFormat()).computeDuration(buf.getLength());
		if (t >= 0)
		    mediaTime[trackID] += t;
		else
		    mediaTime[trackID] = buf.getTimeStamp();
	    }

	} else if (buf.getTimeStamp() < 0) {
	    // This is video with TIME_UNKNOWN.
	    if (systemStartTime >= 0)
	        mediaTime[trackID] = (mediaStartTime + 
				System.currentTimeMillis() - systemStartTime) 
				* 1000000;
	} else
	    mediaTime[trackID] = buf.getTimeStamp();

	timeBase.update();