fi.helsinki.cs.ohtu.mpeg2
Class PESPacketizingOutputStream

java.lang.Object
  extended by java.io.OutputStream
      extended by fi.helsinki.cs.ohtu.mpeg2.PESPacketizingOutputStream
All Implemented Interfaces:
PESPacketAboutToResetListener, java.io.Closeable, java.io.Flushable

public class PESPacketizingOutputStream
extends java.io.OutputStream
implements PESPacketAboutToResetListener

An OutputStream implementation which encapsulates written data to PES packets. Arbitrary PES packet types and header parameters are supported by the notion of an optional template packet. The template packet, which is a PESPacket or a subclass thereof, is filled up with the input data. When the packet is full (with an optional limit of just how full it can be) it is written to the stream and its contents emptied using the reset() method. However, as the reset() method calls insertTemplateBytes() on the subclass, the packet will always have the desired additional header data in it before any data written using this stream class. The stream can wrap either a BitOutputStream or a ProgramStream.


Field Summary
private  BitOutputStream bos
           
private  boolean dirty
           
private  int maxPacketLength
           
private  ProgramStream ps
           
private  PESPacket template
           
 
Constructor Summary
PESPacketizingOutputStream(BitOutputStream stream, PESPacket template)
          Constructs a new instance using an existing PESPacket (or more likely, a subclass) instance as the template and writing directly to a BitOutputStream.
PESPacketizingOutputStream(BitOutputStream stream, StreamID streamID)
          Constructs a new instance using a newly-created PESPacket class with the given stream ID as the template and writing directly to a BitOutputStream.
PESPacketizingOutputStream(ProgramStream stream, PESPacket template)
          Constructs a new instance using an existing PESPacket (or more likely, a subclass) instance as the template and writing to a ProgramStream.
PESPacketizingOutputStream(ProgramStream stream, StreamID streamID)
          Constructs a new instance using a newly-created PESPacket class with the given stream ID as the template and writing to a ProgramStream.
 
Method Summary
 void aboutToReset(PESPacket packet)
          Used to flush data when needed, for example, when the template header fields have been changed.
 void close()
          Closes the stream.
 void flush()
          Flushes the stream, writing the filled-up template packet to the underlying stream.
 int getMaxPacketLength()
          Returns the maximum packet length, as set by setMaxPacketLength() or a constructor.
 PESPacket getTemplate()
          Gets the template packet currently in use.
 BitOutputStream getUnderlyingBOS()
          Returns the BitOutputStream this stream is wrapping.
 ProgramStream getUnderlyingPS()
          Returns the ProgramStream this stream is wrapping.
 void setMaxPacketLength(int length)
          Sets the maximum packet length.
 void setTemplate(PESPacket template)
          Sets the template packet to use.
 void setUnderlyingBOS(BitOutputStream bos)
          Sets the stream to wrap the given BitOutputStream.
 void setUnderlyingPS(ProgramStream ps)
          Sets the stream to wrap the given ProgramStream.
 void write(int byteValue)
          Writes a byte to the stream, filling up the template.
 
Methods inherited from class java.io.OutputStream
write, write
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

bos

private BitOutputStream bos

ps

private ProgramStream ps

template

private PESPacket template

maxPacketLength

private int maxPacketLength

dirty

private boolean dirty
Constructor Detail

PESPacketizingOutputStream

public PESPacketizingOutputStream(BitOutputStream stream,
                                  StreamID streamID)
Constructs a new instance using a newly-created PESPacket class with the given stream ID as the template and writing directly to a BitOutputStream. The maximum length will be set to the maximum allowed PES packet length, 65535 bytes. Use setMaxPacketLength() to change.

Parameters:
stream - The stream to write the resulting packets to.
streamID - The stream ID for the template PESPacket to specify in the common header.

PESPacketizingOutputStream

public PESPacketizingOutputStream(BitOutputStream stream,
                                  PESPacket template)
Constructs a new instance using an existing PESPacket (or more likely, a subclass) instance as the template and writing directly to a BitOutputStream. The template will be reset using its reset() method immediately, so any contents apart from the template bytes written by its overload of insertTemplateBytes() will be lost. The maximum length will be set to the maximum allowed PES packet length, 65535 bytes. Use setMaxPacketLength() to change.

Parameters:
stream - The stream to write the resulting packets to.
template - The template to use, as if setTemplate(template) was called.

PESPacketizingOutputStream

public PESPacketizingOutputStream(ProgramStream stream,
                                  StreamID streamID)
Constructs a new instance using a newly-created PESPacket class with the given stream ID as the template and writing to a ProgramStream. The maximum length will be set to the maximum allowed PES packet length, 65535 bytes. Use setMaxPacketLength() to change.

Parameters:
stream - The stream to write the resulting packets to.
streamID - The stream ID for the template PESPacket to specify in the common header.

PESPacketizingOutputStream

public PESPacketizingOutputStream(ProgramStream stream,
                                  PESPacket template)
Constructs a new instance using an existing PESPacket (or more likely, a subclass) instance as the template and writing to a ProgramStream. The template will be reset using its reset() method immediately, so any contents apart from the template bytes written by its overload of insertTemplateBytes() will be lost. The maximum length will be set to the maximum allowed PES packet length, 65535 bytes. Use setMaxPacketLength() to change.

Parameters:
stream - The stream to write the resulting packets to.
template - The template to use, as if setTemplate(template) was called.
Method Detail

getUnderlyingBOS

public BitOutputStream getUnderlyingBOS()
Returns the BitOutputStream this stream is wrapping. If the stream is wrapping a ProgramStream, null is returned.

Returns:
The stream.

setUnderlyingBOS

public void setUnderlyingBOS(BitOutputStream bos)
Sets the stream to wrap the given BitOutputStream.

Parameters:
bos - The stream to wrap.

getUnderlyingPS

public ProgramStream getUnderlyingPS()
Returns the ProgramStream this stream is wrapping. If the stream is wrapping a BitOutputStream, null is returned.

Returns:
The stream.

setUnderlyingPS

public void setUnderlyingPS(ProgramStream ps)
Sets the stream to wrap the given ProgramStream.

Parameters:
ps - The stream to wrap.

getMaxPacketLength

public int getMaxPacketLength()
Returns the maximum packet length, as set by setMaxPacketLength() or a constructor.

Returns:
The length, in bytes. Will be in range [1..65535].

setMaxPacketLength

public void setMaxPacketLength(int length)
Sets the maximum packet length. The maximum length will be used by the write() implementation to ensure no more that it won't make the length returned by getPacketLength() bigger than the given value. Note that this value doesn't include the PES packet common headers, which are 6 bytes long, but DOES include the length of any template headers included in the packet. This will only affect the operation of future write() calls. This means that if the packet currently in process of being filled already happens to be longer than the newly set maximum length, it will be written with the current amount of bytes inside when write() is next called(). The limit must not be set to a smaller value than the length of the template headers.

Parameters:
length - The new maximum length. Must be in range [1..65535].

getTemplate

public PESPacket getTemplate()
Gets the template packet currently in use. This can be used for eg. adjusting the template packet header parameters. Note that adjusting the header parameters usually makes the PES packet reset itself, so any data lingering in the buffer will be first written in a packet using the old parameters (the parameters at the time of having actually written the data to this stream).

Returns:
The packet.

setTemplate

public void setTemplate(PESPacket template)
Sets the template packet to use. As the data written is buffered in the template, the equivalent of flush() is automatically performed before changing the template used. The new template will be reset using its reset() method immediately, so any contents apart from the template bytes written by its overload of insertTemplateBytes() will be lost. If the new template is the same as the old one, nothing will be done.

Parameters:
template - The new template packet.

write

public void write(int byteValue)
           throws java.io.IOException
Writes a byte to the stream, filling up the template. If the template already has at least getMaxPacketLength() bytes written into it (including the packet type specific headers but not including the six-byte common header), the template will be reset and hence written into the underlying stream first, before appending the new byte. setMaxPacketLength() therefore controls how long packets will be built by this stream.

Specified by:
write in class java.io.OutputStream
Parameters:
byteValue - The byte to write.
Throws:
java.io.IOException - Propagated from flush() and the template stream write.
See Also:
OutputStream.write(int)

flush

public void flush()
           throws java.io.IOException
Flushes the stream, writing the filled-up template packet to the underlying stream. This method can be used to immediately write a packet, even before the packet has grown to getMaxPacketLength() bytes. This can be useful eg. when it is known that no more data will be written in this stream for a while, but it is desired to forward the previously written data as soon as possible. If nothing has been written to the stream after the last flush(), this method does nothing.

Specified by:
flush in interface java.io.Flushable
Overrides:
flush in class java.io.OutputStream
Throws:
java.io.IOException - Propagated from writing the filled-up template to the underlying stream.
See Also:
Flushable.flush()

close

public void close()
           throws java.io.IOException
Closes the stream. Will perform a flush(), and then proceed by closing the underlying bit stream.

Specified by:
close in interface java.io.Closeable
Overrides:
close in class java.io.OutputStream
Throws:
java.io.IOException - Propagated from flush() and closing the underlying stream.
See Also:
Closeable.close()

aboutToReset

public void aboutToReset(PESPacket packet)
                  throws java.io.IOException
Used to flush data when needed, for example, when the template header fields have been changed. Called when PESPacket#reset() has just been called, but the packet is not yet reset. Particularly, this is the last chance to recover any data contained in the about-to-be-reset packet. Subclass header field setters usually cause a reset, so without this event, data would be invariably lost when using those.

Specified by:
aboutToReset in interface PESPacketAboutToResetListener
Parameters:
packet - The packet to be reset.
Throws:
java.io.IOException - Propagated from #flush().
See Also:
PESPacketAboutToResetListener.aboutToReset(PESPacket)