JavaDecoderpublic class JavaDecoder extends VideoCodec
Fields Summary |
---|
private static final int | rMask | private static final int | gMask | private static final int | bMask | private static final boolean | DEBUG | private H263Decoder | javaDecoder | private FrameBuffer | outputFrame | public static final int[] | widths | public static final int[] | heights | private int | videoWidth | private int | videoHeight | private boolean | FormatSizeInitFlag | private int | payloadLength | static boolean | nativeAvail |
Constructors Summary |
---|
public JavaDecoder()
if (plugInExists("com.sun.media.codec.video.vh263.NativeDecoder", PlugInManager.CODEC)) {
try {
JMFSecurityManager.loadLibrary("jmutil");
JMFSecurityManager.loadLibrary("jmvh263");
nativeAvail = true;
} catch (Throwable t) { }
}
supportedInputFormats = new VideoFormat[] {new VideoFormat(VideoFormat.H263),new VideoFormat(VideoFormat.H263_RTP) };
defaultOutputFormats = new VideoFormat[] {new RGBFormat() };
PLUGIN_NAME = "H.263 Decoder";
|
Methods Summary |
---|
public boolean | checkFormat(javax.media.Format format)
if ( (format.getEncoding()).equals(VideoFormat.H263_RTP) ) {
return true;
}
else {
return super.checkFormat(format);
}
| public void | close()
javaDecoder=null;
| boolean | decodeData(javax.media.Buffer inputBuffer, int inputLength, javax.media.Buffer outputBuffer, boolean rtpData)
int ret;
int [] outData = (int [])outputBuffer.getData();
byte[] inputData = (byte [])inputBuffer.getData();
if (inputLength <= 0) {
return false;
}
javaDecoder.initBitstream();
int inputOffset=inputBuffer.getOffset();
if (rtpData) {
// RTPHeader rtpHeader= (RTPHeader) inputBuffer.getHeader();
if (DEBUG) {
System.out.println("[javadecoder:decodeData] inputBuffer.getTimeStamp()=" + inputBuffer.getTimeStamp());
// System.out.println("[javadecoder:decodeData] rtpHeader.getMarker()=" + inputBuffer.getHeader().getMarker());
}
ret = javaDecoder.DecodeRtpPacket(inputData,inputOffset+payloadLength,inputLength,inputData,inputOffset,inputBuffer.getTimeStamp());
if(ret == H263Decoder.H263_RC_PICTURE_FORMAT_NOT_INITED) {
if (DEBUG)
System.out.println("[javadecoder:decodeData] FORMAT_NOT_INITED returing false");
return false;
}
}
else {
ret = javaDecoder.DecodePicture(inputData,inputOffset,true);
}
if (ret == H263Decoder.H263_RC_PICTURE_FORMAT_NOT_SUPPORTED) {
if (DEBUG)
System.out.println("[javadecoder:decodeData] throwing exception - format is not supported ");
throw new RuntimeException("Currently this picture format is not supported!");
}
if (ret == H263Decoder.H263_RC_PICTURE_DONE) {
int outWidth = outputFormat.getSize().width;
int outHeight = outputFormat.getSize().height;
outputFrame = javaDecoder.CurrentFrame;
YCbCrToRGB.convert(outputFrame.Y,outputFrame.Cb,outputFrame.Cr,outData,outputFrame.width,outputFrame.height,outWidth,outHeight,255,4);
return true;
}
else {
if (DEBUG)
System.out.println("[javadecoder:decodeData] ret != H263Decoder.H263_RC_PICTURE_DONE returning false");
return false;
}
| protected javax.media.Format[] | getMatchingOutputFormats(javax.media.Format in)
VideoFormat ivf = (VideoFormat) in;
Dimension inSize = ivf.getSize();
int maxDataLength=ivf.getMaxDataLength();
if ( (ivf.getEncoding()).equals(VideoFormat.H263_RTP) ) {
supportedOutputFormats= new VideoFormat[] {
new RGBFormat (new Dimension(videoWidth,videoHeight),
videoWidth * videoHeight, int[].class,
ivf.getFrameRate(),
32,
rMask, gMask, bMask,
1,videoWidth,
Format.FALSE, // flipped
Format.NOT_SPECIFIED // endian
) /*,
new RGBFormat (null,
Format.NOT_SPECIFIED, int[].class,
32,
rMask, gMask, bMask,
1,Format.NOT_SPECIFIED )*/ };
}
else {
supportedOutputFormats= new VideoFormat[] {
new RGBFormat (new Dimension(inSize),
inSize.width * inSize.height, int[].class,
ivf.getFrameRate(),
32,
rMask, gMask, bMask,
1,inSize.width,
Format.FALSE, // flipped
Format.NOT_SPECIFIED // endian
) };
}
return supportedOutputFormats;
| public static int | getPayloadHeaderLength(byte[] input, int offset)
int l = 0;
byte b = input[offset];
if ( (b & 0x80) != 0) { //mode B or C
if ((b & 0x40) != 0) //mode C
l = 12;
else //mode B
l = 8;
} else { //mode A
l = 4;
}
return l;
| protected void | initDecoder()
javaDecoder = new H263Decoder(true);
| public void | open()
initDecoder();
| public int | process(javax.media.Buffer inputBuffer, javax.media.Buffer outputBuffer)
boolean rtpData = false;
if (!checkInputBuffer(inputBuffer) ) {
return BUFFER_PROCESSED_FAILED;
}
if (isEOM(inputBuffer) ) {
propagateEOM(outputBuffer);
return BUFFER_PROCESSED_OK;
}
VideoFormat ivf=(VideoFormat) inputBuffer.getFormat();
int inLength=inputBuffer.getLength();
int inMaxLength=ivf.getMaxDataLength();
int outMaxLength=outputFormat.getMaxDataLength();
int inputOffset=inputBuffer.getOffset();
byte[] inData =(byte[]) inputBuffer.getData();
if ( (ivf.getEncoding()).equals(VideoFormat.H263_RTP) ) {
rtpData = true;
payloadLength=getPayloadHeaderLength(inData,inputOffset);
if ( (inData[inputOffset+payloadLength] == 0) && (inData[inputOffset+payloadLength+1] == 0) &&
((inData[inputOffset+payloadLength+2] & 0xfc) == 0x80)) {
int s = (inData[inputOffset+payloadLength+4] >> 2) & 0x7;
if ( (videoWidth!=widths[s]) || (videoHeight!=heights[s]) ) {
videoWidth=widths[s];
videoHeight=heights[s];
outputFormat = new RGBFormat (new Dimension(videoWidth,videoHeight),
videoWidth * videoHeight, int[].class,
ivf.getFrameRate(),
32,
rMask, gMask, bMask,
1,videoWidth,
Format.FALSE, // flipped
Format.NOT_SPECIFIED // endian
);
outMaxLength = videoWidth*videoHeight;
if (FormatSizeInitFlag)
videoResized(); // allocate a new decoder only after it was actually used
}
FormatSizeInitFlag=true;
}
if (false == FormatSizeInitFlag) {
return BUFFER_PROCESSED_FAILED;
}
}
int[] outData = validateIntArraySize(outputBuffer,outMaxLength );
/*
* <PATCH> check for insufficient input:
* The decoder might read up to 8 additional bytes before checking for EOS
* It does not bother the native code, but can cause ArrayOutOfBounds
* in Java code
*/
if ( (inLength+8+inputOffset)>inData.length) {
if (DEBUG)
System.out.println("allocating more data for H.263");
int newLength=(inLength > inMaxLength) ? inLength : inMaxLength;
byte[] tempArray=new byte[inputOffset+newLength+8];
System.arraycopy(inData,0,tempArray,0,inLength+inputOffset);
inData=tempArray;
inputBuffer.setData(tempArray);
//inputBuffer.setOffset(0);
}
/*
* <PATCH> pad input with EOS
*/
inData[inputOffset+inLength] = 0;
inData[inputOffset+inLength+1] = 0;
inData[inputOffset+inLength+2]= (byte) 0xfc;
inLength += 3;
inputBuffer.setLength(inLength);
if (rtpData)
inLength-=payloadLength; // this is the length of the bitstream
boolean ret = decodeData(inputBuffer,inLength,outputBuffer,rtpData);
if (ret) {
updateOutput(outputBuffer,outputFormat, outMaxLength, 0);
return BUFFER_PROCESSED_OK;
}
else {
if (DEBUG)
System.out.println("[JavaDecoder] : returning OUTPUT_BUFFER_NOT_FILLED; ");
return OUTPUT_BUFFER_NOT_FILLED;
}
| public void | reset()
initDecoder();
| public javax.media.Format | setInputFormat(javax.media.Format format)Set the data input format.
if (nativeAvail)
return null;
if (super.setInputFormat(format) != null) {
reset();
return format;
} else
return null;
| protected void | videoResized()
initDecoder();
|
|