/*
* @(#)Buffer.java 1.30 02/08/21
*
* Copyright (c) 1996-2002 Sun Microsystems, Inc. All rights reserved.
*/
package javax.media;
import javax.media.format.*;
/**
* A <CODE>Buffer</CODE> is a media-data container that carries media data from one
* processing stage to the next inside of a <code>Player</code> or <code>Processor</code>.
* <CODE>Buffer</CODE> objects are also used to carry data between a buffer stream
* and its handler.
* <p>
* A <code>Buffer</code> object maintains information such as the time stamp,
* length, and <CODE>Format</CODE> of the data it carries, as well as any
* header information that might be required to process the media data.
*
* @see PlugIn
* @see javax.media.protocol.PushBufferStream
* @see javax.media.protocol.PullBufferStream
* @since JMF 2.0
*/
public class Buffer {
/**
* The time stamp of the data held in this <CODE>Buffer</CODE>, in nanoseconds.
* The time stamp marks the time when presentation of this <CODE>Buffer</CODE> is to begin.
* If the start time for this <CODE>Buffer</CODE> is not known, this time stamp is set to
* <CODE>TIME_UNKNOWN</CODE>.
*/
protected long timeStamp = TIME_UNKNOWN;
/**
* The duration of the data held in this <CODE>Buffer</CODE>, in nanoseconds.
* The duration specifies how long it will take for this <CODE>Buffer</CODE>
* to be presented when the playback rate is 1.0.
* If the duration for this <CODE>Buffer</CODE> is not known, it is set to
* <CODE>TIME_UNKNOWN</CODE>.
*/
protected long duration = TIME_UNKNOWN;
/**
* The <CODE>Format</CODE> of the chunk of data in this <CODE>Buffer</CODE>.
*/
protected Format format = null;
/**
* A flag mask that describes the boolean attributes
* enabled for this <CODE>Buffer</CODE>.
* This mask is set to the logical sum of all of the flags that are
* set.
* @see #FLAG_EOM
* @see #FLAG_DISCARD
* @see #FLAG_SILENCE
* @see #FLAG_SID
* @see #FLAG_KEY_FRAME
* @see #FLAG_NO_DROP
* @see #FLAG_NO_WAIT
* @see #FLAG_NO_SYNC
* @see #FLAG_RELATIVE_TIME
* @see #FLAG_SYSTEM_TIME
* @see #FLAG_RTP_TIME
* @see #FLAG_FLUSH
* @see #FLAG_SYSTEM_MARKER
* @see #FLAG_RTP_MARKER
*/
protected int flags = 0;
/**
* The object that actually holds the media data chunk for this <CODE>Buffer</CODE>.
* It can be an array type (such as byte[]) or any other type
* of object. Use <code>instanceOf</code> to determine what type it is.
*/
protected Object data = null ;
/**
* Header information (such as RTP header) for this data chunk.
* It can be of any type.
* Use <code>instanceOf</code> to determine what type it is.
*/
protected Object header = null ;
/**
* For array data type, states how many samples are valid in the array.
* (The array might be larger than the actual media length).
*/
protected int length = 0;
/**
* For array data type, points to the starting point (offset) into the
* array where the valid data begins.
*/
protected int offset = 0;
/**
* The sequence number of this <CODE>Buffer</CODE>. The sequence number of adjacent
* <CODE>Buffer</CODE> objects in a sequence should differ by 1: positive 1 if the
* media is playing forward, negative 1 if the media is played in
* reverse. If the sequence number is not known, SEQUENCE_UNKNOWN
* is specified.
*/
protected long sequenceNumber = SEQUENCE_UNKNOWN;
/**
* Indicates that this <CODE>Buffer</CODE> marks the end of media for the data stream.
* The Buffer might or might not contain valid data to be processed.
* The length and data attributes need to be examined to determine whether or not this
* <CODE>Buffer</CODE> contains valid data.
*/
public final static int FLAG_EOM = (1 << 0);
/**
* Indicates that the media data in this <CODE>Buffer</CODE> should be ignored.
*/
public final static int FLAG_DISCARD = (1 << 1);
/**
* Indicates that this <CODE>Buffer</CODE> contains only silence frames.
*/
public final static int FLAG_SILENCE = (1 << 2);
/**
* Indicates that this <CODE>Buffer</CODE> contains only SID (silence information
* description) frames.
*/
public final static int FLAG_SID = (1 << 3);
/**
* Indicates that this <CODE>Buffer</CODE> starts with a key frame.
*/
public final static int FLAG_KEY_FRAME = (1 << 4);
/**
* Indicates that this <CODE>Buffer</CODE> will not be dropped
* even if the frame is behind the presentation schedule.
*/
public final static int FLAG_NO_DROP = (1 << 5);
/**
* Indicates that this <CODE>Buffer</CODE> will not be waited on
* even if the frame is ahead of the presentation schedule.
*/
public final static int FLAG_NO_WAIT = (1 << 6);
/**
* Indicates that this <CODE>Buffer</CODE> is not to be presented
* in sync with the scheduled presentation time.
* In other words, the <CODE>Buffer</CODE> will not be dropped or waited on if it's behind
* or ahead of schedule.
*/
public final static int FLAG_NO_SYNC = (FLAG_NO_DROP | FLAG_NO_WAIT);
/**
* Indicates that the <CODE>Buffer</CODE> carries a time stamp that's
* relative to the SystemTimeBase.
* This flag is generally set for data transferred from hardware capture
* DataSources that uses the system clock.
*/
public final static int FLAG_SYSTEM_TIME = (1 << 7);
/**
* Indicates that the <CODE>Buffer</CODE> carries a time stamp that's
* in relative time units. This means that individual time stamps are
* not measured against any indentifiable absolute origin--only the
* difference between the time stamps of two consecutive buffers
* carries useful information. (This is the time difference between the
* two packets.)
*/
public final static int FLAG_RELATIVE_TIME = (1 << 8);
/**
* This is a marker bit used by the system. When this flag is set,
* it marks a zero-length <CODE>Buffer</CODE> generated by the system to flush
* the data path. Do not attempt to use or overwrite this flag.
*/
public final static int FLAG_FLUSH = (1 << 9);
/**
* This is a marker bit used by the system. Do not attempt to use
* or overwrite this flag.
*/
public final static int FLAG_SYSTEM_MARKER = (1 << 10);
/**
* This is a marker bit for RTP. Indicates that the <CODE>Buffer</CODE>
* is the last packet of a video frame.
*
*/
public final static int FLAG_RTP_MARKER = (1 << 11);
/**
* Indicates that the <CODE>Buffer</CODE> carries a time stamp that's
* in RTP (NTP) time units.
*/
public final static int FLAG_RTP_TIME = (1 << 12);
/**
* Indicates that some buffer queue in the data flow path from where
* this buffer comes from is overflown.
* When such condition occurs, the processing element should attempt
* to speed up the procesing of this buffer object to reduce the overflow.
*/
public final static int FLAG_BUF_OVERFLOWN = (1 << 13);
/**
* Indicates that some buffer queue in the data flow path from where
* this buffer comes from is underflown.
* When such condition occurs, the processing element should attempt
* to speed up the procesing of this buffer object to reduce the underflow.
*/
public final static int FLAG_BUF_UNDERFLOWN = (1 << 14);
/**
* Indicates that the data is arriving from a live (real-time) source.
*/
public final static int FLAG_LIVE_DATA = (1 << 15);
/**
* The <code>getTimeStamp</code> method return this value if the time
* stamp of the media is not known.
*/
public final static long TIME_UNKNOWN = -1L;
/**
* The <code>getSequenceNumber</code> method returns this value if
* the sequence number is not known.
*/
public final static long SEQUENCE_UNKNOWN = Long.MAX_VALUE - 1;
/**
* Get the <CODE>Format</CODE> of the data in this <CODE>Buffer</CODE>.
*/
public Format getFormat() {
return format;
}
/**
* Sets the <CODE>Format</CODE> of the data in this <CODE>Buffer</CODE>.
* @param format The <CODE>Format</CODE> of the data.
*/
public void setFormat(Format format){
this.format=format;
}
/**
* Gets the mask of the flags set for this <CODE>Buffer</CODE>.
* The integer value of the mask is equal to the logical sum of
* the flags that are set.
* @see #FLAG_EOM
* @see #FLAG_DISCARD
* @see #FLAG_SILENCE
* @see #FLAG_SID
* @see #FLAG_KEY_FRAME
* @see #FLAG_NO_DROP
* @see #FLAG_NO_WAIT
* @see #FLAG_NO_SYNC
* @see #FLAG_RELATIVE_TIME
* @see #FLAG_FLUSH
* @see #FLAG_SYSTEM_MARKER
* @see #FLAG_RTP_MARKER
*/
public int getFlags() {
return flags;
}
/**
* Sets the flag mask for this <CODE>Buffer</CODE>.
* The integer value of the mask is equal to the logical sum of
* the flags that are set.
* @see #FLAG_EOM
* @see #FLAG_DISCARD
* @see #FLAG_SILENCE
* @see #FLAG_SID
* @see #FLAG_KEY_FRAME
* @see #FLAG_NO_DROP
* @see #FLAG_NO_WAIT
* @see #FLAG_NO_SYNC
* @see #FLAG_RELATIVE_TIME
* @see #FLAG_FLUSH
* @see #FLAG_SYSTEM_MARKER
* @see #FLAG_RTP_MARKER
*/
public void setFlags(int flags) {
this.flags = flags;
}
/**
* Checks whether or not this <CODE>Buffer</CODE> marks the end of the media stream.
* Even it <CODE>isEOM</CODE> returns <CODE>true</CODE>, the <CODE>Buffer</CODE> might still
* contain valid data--check the length of the <CODE>Buffer</CODE>.
* <p>
* This method provides a convenient alternative to using <CODE>getFlags</CODE>
* to check the EOM flag.
* @return <CODE>true</CODE> if the EOM flag is enabled, <CODE>false</CODE> if it is not.
* @see #getFlags
* @see #FLAG_EOM
*/
public boolean isEOM() {
return (flags & FLAG_EOM) != 0;
}
/**
* Sets the EOM flag for this <CODE>Buffer</CODE>. If the EOM flag is enabled, this
* is the last <CODE>Buffer</CODE> in the media stream.
* <p>
* This method provides a convenient alternative to using <CODE>setFlags</CODE>
* to enable or disable the EOM flag.
* @param eom A boolean value that contains the EOM status of the <CODE>Buffer</CODE>. Set to
* <CODE>true</CODE> to enable the EOM flag, <CODE>false</CODE> to disable the flag.
* @see #setFlags
* @see #FLAG_EOM
*/
public void setEOM(boolean eom) {
if (eom)
flags |= FLAG_EOM;
else
flags &= ~FLAG_EOM;
}
/**
* Checks whether or not this <CODE>Buffer</CODE> is to be discarded.
* <p>
* This method provides a convenient alternative to using <CODE>getFlags</CODE>
* to check the DISCARD flag.
* @return <CODE>true</CODE> if the DISCARD flag is enabled, <CODE>false</CODE> if it is not.
* @see #getFlags
* @see #FLAG_DISCARD
*/
public boolean isDiscard() {
return (flags & FLAG_DISCARD) != 0;
}
/**
* Sets the DISCARD flag for this <CODE>Buffer</CODE>. If the DISCARD flag is enabled,
* this <CODE>Buffer</CODE> is to be discarded.
* <p>
* This method provides a convenient alternative to using <CODE>setFlags</CODE>
* to enable or disable the DISCARD flag.
* @param discard A boolean value that contains the DISCARD status of the <CODE>Buffer</CODE>. Set to
* <CODE>true</CODE> to enable the EOM flag, <CODE>false</CODE> to disable the flag.
* @see #setFlags
* @see #FLAG_DISCARD
*/
public void setDiscard(boolean discard) {
if (discard)
flags |= FLAG_DISCARD;
else
flags &= ~FLAG_DISCARD;
}
/**
* Gets the internal data object that holds the media chunk contained in this <CODE>Buffer</CODE>.
* @return The data object that holds the media chunk for this <CODE>Buffer</CODE>.
* It can be an array type (such as byte[]) or any other type
* of object. Use <code>instanceOf</code> to determine what type it is.
* @see #data
*/
public Object getData() {
return data;
}
/**
* Sets the internal data object that holds the media chunk.
* @param data The data object that holds the media data chunk for this <CODE>Buffer</CODE>.
* It can be an array type (such as byte[]) or any other type
* of object.
* @see #data
**/
public void setData(Object data) {
this.data = data;
}
/**
* Gets the header information for the media chunk contained in this <CODE>Buffer</CODE>.
* @return The object that holds the header information. Use <code>instanceOf</code>
* to determine what type the header object is.
* @see #header
*/
public Object getHeader() {
return header;
}
/**
* Sets the header information for the media chunk.
* @param header The header object that holds the media data chunk for this <CODE>Buffer</CODE>.
* @see #header
**/
public void setHeader(Object header) {
this.header = header;
}
/**
* Gets the length of the valid data in this <CODE>Buffer</CODE> if the data is held in an array.
* @return The length of the valid data in the data array that holds the media chunk
* for this <CODE>Buffer</CODE>.
* @see #length
*/
public int getLength() {
return length;
}
/**
* Sets the length of the valid data stored in this <CODE>Buffer</CODE> if the data
* is held in an array.
* @param length The length of the valid data in the data array that holds the
* media chunk for this <CODE>Buffer</CODE>.
* @see #length
*/
public void setLength(int length){
this.length=length;
}
/**
* If the media chunk for this <CODE>Buffer</CODE> is held in an array, gets the
* offset into the data array where the valid data begins.
*
*/
public int getOffset() {
return offset;
}
/**
* If the media chunk for this <CODE>Buffer</CODE> is held in an array,
* sets the offset into the array where the valid data begins.
* @param offset The starting point for the valid data.
* @see #offset
*/
public void setOffset(int offset) {
this.offset = offset;
}
/**
* Gets the time stamp of this <CODE>Buffer</CODE>.
* @return The <CODE>Buffer</CODE> time stamp, in nanoseconds.
* @see #timeStamp
*/
public long getTimeStamp() {
return timeStamp;
}
/**
* Sets the time stamp of this <CODE>Buffer</CODE>.
* @param timeStamp The time stamp for the <CODE>Buffer</CODE>, in nanoseconds.
* @see #timeStamp
*/
public void setTimeStamp(long timeStamp) {
this.timeStamp = timeStamp;
}
/**
* Gets the duration of this <CODE>Buffer</CODE>.
* @return The <CODE>Buffer</CODE> duration, in nanoseconds.
* @see #duration
*/
public long getDuration() {
return duration;
}
/**
* Sets the duration of this <CODE>Buffer</CODE>.
* @param duration The duration for the <CODE>Buffer</CODE>, in nanoseconds.
* @see #duration
*/
public void setDuration(long duration) {
this.duration = duration;
}
/**
* Sets the sequence number of this <CODE>Buffer</CODE>. Sequence numbers
* increase or decrease by 1 for each sequential <CODE>Buffer</CODE>, indicating
* the order in which the data is to be processed. Can be used
* to identify lost samples of data.
* @param number The sequence number for the <CODE>Buffer</CODE>.
* @see #sequenceNumber
*/
public void setSequenceNumber(long number) {
sequenceNumber = number;
}
/**
* Gets the sequence number of this <CODE>Buffer</CODE>.
* @return The sequence number of this <CODE>Buffer</CODE>.
* @see #sequenceNumber
*/
public long getSequenceNumber() {
return sequenceNumber;
}
/**
* Copy the attributes from the specified <CODE>Buffer</CODE> into this
* <CODE>Buffer</CODE>
* @param buffer The input <CODE>Buffer</code> the copy the attributes from.
*/
public void copy(Buffer buffer) {
copy(buffer, false);
}
/**
* Copy the attributes from the specified <CODE>Buffer</CODE> into this
* <CODE>Buffer</CODE>. If swapData is true, the data values are swapped
* between the buffers, otherwise the data value is copied.
* @param buffer The input <CODE>Buffer</code> the copy the attributes from.
* @param swapData Specifies whether the data objects are to be swapped.
*/
public void copy(Buffer buffer, boolean swapData) {
if (swapData) {
Object temp = data;
data = buffer.data;
buffer.data = temp;
} else {
data = buffer.data;
}
header = buffer.header;
format = buffer.format;
length = buffer.length;
offset = buffer.offset;
timeStamp = buffer.timeStamp;
duration = buffer.duration;
sequenceNumber = buffer.sequenceNumber;
flags = buffer.flags;
}
/**
* Clone a buffer.
*/
public Object clone() {
Buffer buf = new Buffer();
Object data = getData();
if (data != null) {
if (data instanceof byte[])
buf.data = ((byte[])data).clone();
else if (data instanceof int[])
buf.data = ((int[])data).clone();
else if (data instanceof short[])
buf.data = ((short[])data).clone();
else
buf.data = data;
}
if (header != null) {
if (header instanceof byte[])
buf.header = ((byte[])header).clone();
else if (header instanceof int[])
buf.header = ((int[])header).clone();
else if (header instanceof short[])
buf.header = ((short[])header).clone();
else
buf.header = header;
}
buf.format = format;
buf.length = length;
buf.offset = offset;
buf.timeStamp = timeStamp;
buf.duration = duration;
buf.sequenceNumber = sequenceNumber;
buf.flags = flags;
return buf;
}
}
|