|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectfi.helsinki.cs.ohtu.mpeg2.ProgramStreamMuxer
public class ProgramStreamMuxer
Implements an MPEG-2 program stream multiplexer. It supports both constant and variable bitrate multiplexing.
Multiplexing consists roughly of the following phases:
This class implements the packet scheduling and multiplex generation.
For high-level stream handling, see AudioStream
and
VideoStream
. A generic packetizer for elementary streams is
AVPacketizer
.
The multiplexer generates program stream in fixed sized chunks (the exact size can be set). This is very useful if the stream has to be aligned to storage medium sectors (as is with DVD and VCD). In general, it makes the multiplexing process easier to implement. As a downside, the use of chunks makes the multiplexer a little stupid: Every now and then there will be some padding just to keep up the alignment. Thus a successful multiplex requires a higher bitrate than really necessary.
Multiplexing special formats, like for a DVD or VCD, is not supported out of the box.
A chunk contains always at most one PES packet of one elementary stream. A PES packet containing data might contain stuffing bytes. The data packet might be followed by a padding packet in order to to match with the chunk size. Some chunks are purely for padding: they contain no real data. Those are needed when there is not useful data available and constant bit rate has to be maintained.
An example of a 2048 byte chunk with a pack header and some padding:
+----------+-------------------------+-----------+ | pack hdr | data PES packet | padding | +----------+-------------------------+-----------+ |------------------- 2048 bytes -----------------|
The use of this multiplexer is divided in two phases: initialization
and stream generation. The initialization phase starts when
a ProgramStreamMuxer
instance is created. During the
initialization program stream parameters can be adjusted and input
stream added. The multiplexer transitions from initialization to
stream generation when the first piece of input data arrives.
The stream generation phase continues until the last open input
stream is closed.
IOException
s are handled in a synchronous manner. Any
caught IOException
is stored. The stored exception
can be polled later. The rationale for this is to keep the gory
details of IO out of packetization and streaming classes.
Otherwise an IOException
might pop out of any method
writing data to the multiplexer. The current implementation
does not permit continuing multiplexing after an
IOException
has been caught.
This multiplexer is not thread-safe.
Here is an example how to multiplex a program stream of 512 kbit/s:
BitOutputStream bout = new BitOutputStream(...); ProgramStreamMuxer psmux = new ProgramStreamMuxer(bout, 512000); AudioStream as = new AudioStream(); VideoStream vs = new VideoStream(); psmux.addStream(as.getPacketizer(0)); psmux.addStream(vs.getPacketizer(0)); ... for (...) { ... /* encode audio */ ... as.write(audioFrame); /* encode video */ ... vs.write(pictureHeader, pictureCodingExtHeader); vs.write(sliceHeader); vs.write(...); ... ... } as.close(); vs.close(); /* The multiplexer does not close the output stream. */ bout.close();
Nested Class Summary | |
---|---|
private static class |
ProgramStreamMuxer.StreamDesc
|
Field Summary | |
---|---|
private BitOutputStream |
bout
|
private long |
bytesOut
|
private long |
chunkCount
|
private int |
chunkSize
|
private int |
chunksPerPack
|
private static int |
DEFAULT_CHUNK
|
private static double |
DEFAULT_PACK_RATE
|
private boolean |
initing
|
private java.io.IOException |
ioe
|
private java.util.List<ProgramStreamMuxer.StreamDesc> |
streams
|
private SystemHeader |
syshdr
|
private boolean |
syshdrOnce
|
Constructor Summary | |
---|---|
ProgramStreamMuxer(BitOutputStream stream,
int bitrate)
Creates a program stream multiplexer. |
|
ProgramStreamMuxer(BitOutputStream stream,
int bitrate,
int chunkSize,
double packRate)
Creates a program stream multiplexer. |
Method Summary | |
---|---|
void |
addStream(AVPacketizer avp)
Adds a stream to this multiplex. |
void |
addStream(AVPacketizer avp,
long tboff)
Adds a stream to this multiplex. |
private long |
bytesToTicks(long bcount)
Gets how many system clock ticks it takes to transmit the given number of bytes. |
private void |
calcDelays()
Calculates startup delays for the streams and adjusts timebase offsets accordingly. |
private float |
getChunkRate()
Returns the chunk rate. |
int |
getChunksPerPack()
Returns the pack rate in chunks per pack. |
float |
getPackRate()
Gets the pack rate. |
boolean |
isFixedRate()
Returns whether the multiplex rate is fixed. |
boolean |
isSystemHeaderOnce()
Gets whether the system header is written only once, along with the first pack header. |
void |
packetDataAvail(AVPacketizer p)
Acknowledges this multiplexer that a paketizer has some data available. |
java.io.IOException |
pollIOException()
Returns pending IOException , or returns null ,
if no exception has been caught. |
private void |
schedule()
Determines from which input stream to pull data into the multiplex. |
private long |
scrNow()
Returns the current SCR. |
void |
setChunksPerPack(int chunksPerPack)
Sets the pack rate in chunks per pack. |
void |
setFixedRate(boolean fixedRate)
Sets whether a fixed rate multiplex is generated. |
void |
setPackRate(double packRate)
Sets the pack rate. |
void |
setSystemHeaderOnce(boolean syshdrOnce)
Sets whether the system header is written only once, along the first pack header. |
private boolean |
writeChunk(AVPacketizer avp)
Writes a chunk of data. |
private void |
writePadding()
Writes a padding chunk. |
private void |
writePaddingPacket(int size)
Writes a padding PES packet. |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
---|
private static final int DEFAULT_CHUNK
private static final double DEFAULT_PACK_RATE
private final int chunkSize
private int chunksPerPack
private long chunkCount
private long bytesOut
private boolean syshdrOnce
private boolean initing
private final BitOutputStream bout
private final SystemHeader syshdr
private final java.util.List<ProgramStreamMuxer.StreamDesc> streams
private java.io.IOException ioe
Constructor Detail |
---|
public ProgramStreamMuxer(BitOutputStream stream, int bitrate)
stream
- the stream to write the multiplex intobitrate
- the bitrate of the multiplexed stream, in bits/spublic ProgramStreamMuxer(BitOutputStream stream, int bitrate, int chunkSize, double packRate)
stream
- the stream to write the multiplex intobitrate
- the bitrate of the multiplexed stream, in bits/schunkSize
- the chunk sizepackRate
- the pack rate, in packs per secondMethod Detail |
---|
public float getPackRate()
public int getChunksPerPack()
public boolean isFixedRate()
Fixed rate multiplexing is the default.
true
if the multiplex rate is fixedpublic boolean isSystemHeaderOnce()
true
if the system header is written only oncepublic void setPackRate(double packRate)
packRate
but no more
than the chunk rate.
packRate
- the pack rate, in packs per secondpublic void setChunksPerPack(int chunksPerPack)
chunksPerPack
- the pack rate in chunks per packpublic void setFixedRate(boolean fixedRate)
fixedRate
-
true if the multiplex is fixed rateisFixedRate()
public void setSystemHeaderOnce(boolean syshdrOnce)
syshdrOnce
- true
if the system header is written
only oncepublic java.io.IOException pollIOException()
IOException
, or returns null
,
if no exception has been caught. At the moment, a pending
exception is not cleared when this method is called.
IOException
or null
public void addStream(AVPacketizer avp, long tboff)
avp
- the packetizer for the stream to be addedtboff
- the time base offset, in ticks of the 90kHz clock
java.lang.IllegalStateException
- if called during stream generationpublic void addStream(AVPacketizer avp)
avp
- the packetizer for the stream to be added
java.lang.IllegalStateException
- if called during stream generationpublic void packetDataAvail(AVPacketizer p)
packetDataAvail
in interface PacketizerListener
p
- the packetizer which has data availableprivate void schedule() throws java.io.IOException
java.io.IOException
private boolean writeChunk(AVPacketizer avp) throws java.io.IOException
sp
- the packetizer to read a data packet from
true
if a chunk was written
java.io.IOException
private void writePaddingPacket(int size) throws java.io.IOException
size
- the size of the padding packet, has to be at least 7
java.io.IOException
private void writePadding() throws java.io.IOException
java.io.IOException
private long scrNow()
private float getChunkRate()
private void calcDelays()
private long bytesToTicks(long bcount)
bcount
- the number of bytes
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |