DePacketizerpublic class DePacketizer extends VideoCodec Neon Media MPEG-4 Video
RTP De-Packetizer |
Fields Summary |
---|
private static String | IN_ENCODING | private static String | OUT_ENCODING | private static final int | DEF_WIDTH | private static final int | DEF_HEIGHT | private boolean | firstFrame | private MP4VFrame | currentFrame | private short | seqNum | private final int | FRAME_BUFFER_INITIAL_SIZE |
Constructors Summary |
---|
public DePacketizer()
System.err.println(this.getClass().getName() + " constructor called.");
PLUGIN_NAME = "Neon MP4V RTP DePacketizer";
inputFormats = supportedInputFormats = new VideoFormat[] { new VideoFormat(IN_ENCODING), new VideoFormat("MP4V-ES"), new VideoFormat("MP4V-ES/90000") };
defaultOutputFormats = new VideoFormat[] { new VideoFormat(OUT_ENCODING) };
/* //DEBUG
try {
dumpFile = new File("dump.m4v");
packDumpFile = new File("packdump.m4v");
completeDFile = new File("completedump.m4v");
logFile = new File("nmp.log");
dumpOut = new FileOutputStream(dumpFile);
packDumpOut = new FileOutputStream(packDumpFile);
completeDOut = new FileOutputStream(completeDFile);
logOut = new FileOutputStream(logFile);
log = new PrintStream(logOut);
} catch (FileNotFoundException e) {
System.err.println("mp4v.DePacketizer: failed to open dump files: " + e.getMessage());
e.printStackTrace();
}
*/ //DEBUG
|
Methods Summary |
---|
private static boolean | canStartStream(javax.media.Buffer buffer)
byte[] payload = (byte[])buffer.getData();
int offset = buffer.getOffset();
//System.err.println("mp4v.DePacketizer: offset = " + offset);
int length = 32; // VOL SHOULD be in the first 32 bytes so don't bother scanning entire buffer
if (buffer.getLength() <= length) return false;
boolean keep_looking = true;
int currentCode = (payload[offset] & 0xff) << 24 | (payload[offset+1] & 0xff) << 16 | (payload[offset+2] & 0xff) << 8 | (payload[offset+3] & 0xff);
for (int i=4; i < length; i++) {
if ((currentCode & 0xfffffff0) == 0x00000120) return true;
if (currentCode == 0x000001b0) System.err.println("MP4VFrame.canStartStream: frame has VS header");
if (currentCode == 0x000001b5) System.err.println("MP4VFrame.canStartStream: frame has VO header");
//System.err.println("MP4VFrame.canStartStream:0x" + Integer.toHexString(currentCode));
currentCode = (currentCode << 8) | (payload[offset+i] & 0xff);
}
return false; // VOL not found
| private void | completeTransfer(javax.media.Buffer inBuffer, javax.media.Buffer outBuffer)
// System.err.println("mp4v.DePacketizer: completeTransfer called");
if (outputFormat == null) System.err.println("mp4v.DePacketizer: outputFormat NULL!!!!!!!!!!");
//SANITY CHECK
if (!isFrameStart(currentFrame.getFrameBuffer(), 0)) {
System.err.println("((((((mp4v.DePacketizer: FRAME CORRUPTED!!))))))");
System.exit(1);
}
outBuffer.setFormat(outputFormat);
outBuffer.setData(currentFrame.getFrameBuffer());
outBuffer.setOffset(0);
outBuffer.setDuration((long)(((VideoFormat)outputFormat).getFrameRate() + 0.5));
outBuffer.setSequenceNumber(seqNum++); //FIXME roll over??
outBuffer.setTimeStamp(currentFrame.getTimeStamp());
outBuffer.setLength(currentFrame.getDataLength());
/* //DEBUG
try {
dumpOut.write(currentFrame.getFrameBuffer(), 0, currentFrame.getDataLength());
} catch (Exception e) {
System.err.println("mp4v.DePacketizer: failed to write frame: " + e.getMessage());
e.printStackTrace();
}
*/ //DEBUG
currentFrame = null;
| public java.lang.String | getName()
return PLUGIN_NAME;
| public javax.media.Format[] | getSupportedOutputFormats(javax.media.Format f)
System.err.println("mp4v.DePacketizer: getting for f = " + f);
if (f == null) return defaultOutputFormats;
else if (f.getEncoding().equalsIgnoreCase(IN_ENCODING)) {
if (f instanceof VideoFormat) {
VideoFormat vf = (VideoFormat)f;
VideoFormat supOutFmt = new VideoFormat(OUT_ENCODING, vf.getSize() == null ? new Dimension(DEF_WIDTH, DEF_HEIGHT):vf.getSize(), vf.getMaxDataLength(), Format.byteArray, vf.getFrameRate());
System.err.println("mp4v.DePacketizer: supported Output Format = " + supOutFmt);
return new Format[] { supOutFmt };
} else return new Format[] {new VideoFormat(OUT_ENCODING, new Dimension(DEF_WIDTH, DEF_HEIGHT), Format.NOT_SPECIFIED, Format.byteArray, Format.NOT_SPECIFIED) };
}
System.err.println("mp4v.DePacketizer: getSupportedOutputFormats f = " + f);
return new Format[0];
| private static boolean | isFrameStart(javax.media.Buffer buffer) // 8KB
/* //DEBUG
private File dumpFile;
private File packDumpFile;
private File completeDFile;
private File logFile;
private FileOutputStream dumpOut;
private FileOutputStream packDumpOut;
private FileOutputStream completeDOut;
private FileOutputStream logOut;
private PrintStream log;
*/ //DEBUG
Object data = buffer.getData();
byte[] payload = (byte[])data;
int offset = buffer.getOffset();
return isFrameStart(payload, offset);
| private static boolean | isFrameStart(byte[] payload, int offset)
int firstBytes = (payload[offset] & 0xff) << 16 | (payload[offset+1] & 0xff) << 8 | (payload[offset+2] & 0xff);
// first 3 bytes of a system code
return firstBytes == 0x000001;
| public synchronized int | process(javax.media.Buffer inBuffer, javax.media.Buffer outBuffer)
if (firstFrame && !(inBuffer.getData() instanceof byte[])) { // assume that if the first inBuffers are byte arrays, all are
System.err.println("MP4VFrame.isFrameStart: payload is not byte[]");
return OUTPUT_BUFFER_NOT_FILLED;
}
//DEBUG
//HACK:Sun RTP RECEIVE BUG
// Sun RTP seems to require regular I/O, otherwise it seldom delivers received packets
System.err.println("mp4v.DePacketizer: process() inBuffer.getLength() = " + inBuffer.getLength());
//DEBUG
if (isEOM(inBuffer)) {
propagateEOM(outBuffer);
return BUFFER_PROCESSED_OK;
}
if (inBuffer.isDiscard()) {
updateOutput(outBuffer, outputFormat, 0, 0);
outBuffer.setDiscard(true);
return OUTPUT_BUFFER_NOT_FILLED;
}
/* //DEBUG
try {
completeDOut.write((byte[])inBuffer.getData(), inBuffer.getOffset(), inBuffer.getLength());
} catch (IOException e) {
System.err.println("mp4v.DePacketizer: couldn't write to complete dump: " + e.getMessage());
e.printStackTrace();
}
*/ //DEBUG
//System.err.println("mp4v.DePacketizer: process packet");
// lost RTP fragment packet(s) so drop frame
if (currentFrame != null && inBuffer.getTimeStamp() != currentFrame.getTimeStamp()) {
System.err.println("mp4v.DePacketizer: DROP FRAME:timestamp mismatch: got(" + inBuffer.getTimeStamp() + ") on packet " + inBuffer.getSequenceNumber() + ", expected(" + currentFrame.getTimeStamp() + ")");
currentFrame = null;
// frameBuffer.clear();
}
// check to see if packet is first of a frame
if (currentFrame == null && isFrameStart(inBuffer)) {
// ensure first frame given to encoder has needed configuration information
if (firstFrame && !canStartStream(inBuffer)) return PlugIn.OUTPUT_BUFFER_NOT_FILLED;
if (firstFrame) System.err.println(">>>> mp4v.DePacketizer: START STREAM");
currentFrame = new MP4VFrame(inBuffer);
firstFrame = false;
} else {
if (currentFrame == null) {
System.err.println("^^^^mp4v.DePacketizer: DROP PACKET " + inBuffer.getSequenceNumber() + ": no current frame and packet cannot start frame.");
return PlugIn.OUTPUT_BUFFER_NOT_FILLED;
}
// System.err.println("mp4v.DePacketizer: adding packet to frame");
currentFrame.add(inBuffer);
}
// check to see if entire frame should now have been received
if ((inBuffer.getFlags() & Buffer.FLAG_RTP_MARKER) != 0) {
if (!currentFrame.isMissingFragments()) {
completeTransfer(inBuffer, outBuffer);
currentFrame = null;
// System.err.println("____mp4v.DePacketizer: delivering frame._____");
return PlugIn.BUFFER_PROCESSED_OK;
} else {
// frame incomplete and last packet received, so drop
System.err.println("&&&&mp4v.DePacketizer: DROP FRAME:missing fragments");
currentFrame = null;
return PlugIn.OUTPUT_BUFFER_NOT_FILLED;
}
}
// System.err.println("mp4v.DePacketizer: output buffer not filled");
return PlugIn.OUTPUT_BUFFER_NOT_FILLED;
| public javax.media.Format | setOutputFormat(javax.media.Format f)
VideoFormat vf = (VideoFormat)f;
if (!f.getEncoding().equalsIgnoreCase(OUT_ENCODING)) {
System.err.println("mp4v.DePacketizer: setOutputFormat received unsupported encoding: " + f.getEncoding());
return null;
}
System.err.println("mp4v.DePacketizer: setOutputFormat received format with size: " + vf.getSize());
outputFormat = new VideoFormat(OUT_ENCODING, vf.getSize() == null ? new Dimension(DEF_WIDTH, DEF_HEIGHT):vf.getSize(), vf.getMaxDataLength(), Format.byteArray, vf.getFrameRate());
return outputFormat;
|
|