FileDocCategorySizeDatePackage
BasicTrack.javaAPI DocJMF 2.1.1e7309Mon May 12 12:20:52 BST 2003com.sun.media.parser

BasicTrack

public class BasicTrack extends Object implements Track

Fields Summary
private Format
format
private boolean
enabled
protected Time
duration
private Time
startTime
private int
numBuffers
private int
dataSize
private PullSourceStream
stream
private long
minLocation
private long
maxLocation
private long
maxStartLocation
private BasicPullParser
parser
private long
sequenceNumber
private TrackListener
listener
private long
seekLocation
private long
mediaSizeAtEOM
private boolean
warnedUserOfReadPastEOM
Constructors Summary
public BasicTrack(BasicPullParser parser, Format format, boolean enabled, Time duration, Time startTime, int numBuffers, int dataSize, PullSourceStream stream)


      
	              
	             
	this(parser, format,  enabled,  duration,  startTime,
	     numBuffers, dataSize, stream,
	     0L, Long.MAX_VALUE);
    
public BasicTrack(BasicPullParser parser, Format format, boolean enabled, Time duration, Time startTime, int numBuffers, int dataSize, PullSourceStream stream, long minLocation, long maxLocation)
Note to implementors who want to use this class. If the maxLocation is not known, then specify Long.MAX_VALUE for this parameter

	this.parser = parser;

	this.format = format;
	this.enabled = enabled;
	this.duration = duration;
	this.startTime = startTime;
	this.numBuffers = numBuffers;
	this.dataSize = dataSize;
	this.stream = stream;
	this.minLocation = minLocation;
	this.maxLocation = maxLocation;
	maxStartLocation = maxLocation - dataSize;
    
Methods Summary
public javax.media.TimegetDuration()

	return duration;
    
public javax.media.FormatgetFormat()

	return format;
    
public longgetMediaSizeAtEOM()

	return mediaSizeAtEOM; // updated when EOM implied by IOException occurs
    
public synchronized longgetSeekLocation()

	return seekLocation;
    
public javax.media.TimegetStartTime()

	return startTime;
    
public booleanisEnabled()

	return enabled;
    
public javax.media.TimemapFrameToTime(int frameNumber)

	return TIME_UNKNOWN;
    
public intmapTimeToFrame(javax.media.Time t)

	return FRAME_UNKNOWN;
    
public voidreadFrame(javax.media.Buffer buffer)


	if (buffer == null)
	    return;

	if (!enabled) {
	    buffer.setDiscard(true);
	    return;
	}

	buffer.setFormat(format); // Need to do this every time ???
	Object obj = buffer.getData();
	byte[] data;
	long location;
	boolean needToSeek;
	
	synchronized(this) {
	    if (seekLocation != -1) {
		location = seekLocation;
		if (seekLocation < maxLocation)
		    seekLocation = -1;
		needToSeek = true;
	    } else {
		location = parser.getLocation(stream);
		needToSeek = false;
	    }
	}

	int needDataSize;

	//TODO START
	if (location < minLocation) {
	    // TODO: should probably seek or skip to minLocation
	    buffer.setDiscard(true);
	    return;
	} else if (location >= maxLocation) {
	    buffer.setLength(0);
	    buffer.setEOM(true);
	    return;
	} else if (location > maxStartLocation) {
	    needDataSize = dataSize - (int) (location - maxStartLocation);
	} else {
	    needDataSize = dataSize;
	}
	//TODO END

	if  ( (obj == null) ||
	      (! (obj instanceof byte[]) ) ||
	      ( ((byte[])obj).length < needDataSize) ) {
	    // System.out.println("readFrame creating new byte data of size " + needDataSize);
	    data = new byte[needDataSize];
	    buffer.setData(data);
	} else {
	    data = (byte[]) obj;
	}
	try {
	    if ( (parser.cacheStream != null) && (listener != null) ) {
		if ( parser.cacheStream.willReadBytesBlock(location, needDataSize) ) {
		    // System.out.println("read will block: " + location + " : " +
		    // needDataSize);
		    listener.readHasBlocked(this);
		}
	    }
	    if (needToSeek) {
		// TODO: need to handle case where the stream is not seekable and
		// caching is not beeing done (ie cacheStream is null)
		long pos = ((javax.media.protocol.Seekable)stream).seek(location);
		if ( pos == com.sun.media.protocol.BasicSourceStream.LENGTH_DISCARD) {
		    buffer.setDiscard(true);
		    return;
		}
	    }
	    if (parser.getMediaTime() != null)
		buffer.setTimeStamp(parser.getMediaTime().getNanoseconds());
	    else
		buffer.setTimeStamp(Buffer.TIME_UNKNOWN);
	    buffer.setDuration(Buffer.TIME_UNKNOWN);

	    int actualBytesRead = parser.readBytes(stream, data, needDataSize);
	    buffer.setOffset(0);
	    buffer.setLength(actualBytesRead);
	    // TODO: need setSequenceNumber and getSequenceNumber in Buffer
	    buffer.setSequenceNumber(++sequenceNumber);
// 	    System.out.println("Time stamp: " + (buffer.getTimeStamp())/1.E9);
	} catch (IOException e) {
	    if (maxLocation != Long.MAX_VALUE) {
		// Known maxLocation. So, this is a case of
		// deliberately reading past EOM
		if (!warnedUserOfReadPastEOM) {
		    com.sun.media.Log.warning("Warning: Attempt to read past End of Media");
		    com.sun.media.Log.warning("This typically happens if the duration is not known or");
		    com.sun.media.Log.warning("if the media file has incorrect header info");
		    warnedUserOfReadPastEOM = true;
		}
		buffer.setLength(0); // Need this??
		buffer.setEOM(true);
	    } else {
		// Unknown maxLocation, due to unknown content length
		// EOM reached before the required bytes could be read.
		long length = parser.streams[0].getContentLength();
		if ( length != SourceStream.LENGTH_UNKNOWN ) {
		    // If content-length is known, discard this buffer, update
		    // maxLocation, maxStartLocation and mediaSizeAtEOM.
		    //  The next readFrame will read the remaining data till EOM.
		    maxLocation = length;
		    maxStartLocation = maxLocation - dataSize;
		    mediaSizeAtEOM = maxLocation - minLocation;
		    buffer.setLength(0); // Need this??
		    buffer.setDiscard(true);
		} else {
		    // Content Length is still unknown after an IOException.
		    // We can still discard this buffer and keep discarding
		    // until content length is known. But this may go into
		    // into an infinite loop, if there are real IO errors
		    // So, return EOM
		    maxLocation = parser.getLocation(stream);
		    maxStartLocation = maxLocation - dataSize;
		    mediaSizeAtEOM = maxLocation - minLocation;
		    buffer.setLength(0); // Need this??
		    buffer.setEOM(true);

		}
			   
	    }
	    // TODO: $$$$ Update maxFrame and duration
	}
	
	// System.out.println("parser's location: " + parser.getLocation(stream));
	// parser.getMediaTime(); // Side effect printout
    
public voidsetEnabled(boolean t)

	enabled = t;
    
public synchronized voidsetSeekLocation(long location)

	seekLocation = location;
    
public voidsetTrackListener(javax.media.TrackListener l)

	listener = l;