NativeEncoderpublic class NativeEncoder extends VideoCodec
Fields Summary |
---|
public static final String | a_copyright_noticeLicensed Materials - Property of IBM
"Restricted Materials of IBM"
5648-B81
(c) Copyright IBM Corporation 1997,1999 All Rights Reserved
US Government Users Restricted Rights - Use, duplication or
disclosure restricted by GSA ADP Schedule Contract with
IBM Corporation. | static final int[] | widths | static final int[] | heights | private int | videoWidth | private int | videoHeight | int | nativeFormat | static final int | DEFAULT_RTP_MTU | static final int | MAX_RTP_MTU | static final int | DEFAULT_MAX_OUTPUT_LENGTH | public int | maxOutputLength | public int | targetOutputLength | long | timeStamp | long | sequenceNumber | long | deltaFrames | boolean | useRtp | Control[] | controls | float | sourceFrameRate | float | targetFrameRate | int | minBitRate | int | maxBitRate | int | useBitRate | int | iFramePeriod | int | frameDecimation | int | frame2skip | boolean | initCompleted | boolean | settingsChanged | boolean | dropFrame | boolean | okToDrop | EncodeControl | encodeControl | private int | nativeData | private int | prevTr | private int | tr | public boolean | frameDone | private int | outputLength | private boolean | interFlag |
Constructors Summary |
---|
public NativeEncoder()
// Constructor
/// System.out.println("[h263Encoder:Constructor]");
supportedInputFormats = new VideoFormat[] {
new YUVFormat(YUVFormat.YUV_420)
};
defaultOutputFormats = new VideoFormat[] {
new VideoFormat(VideoFormat.H263),
new VideoFormat(VideoFormat.H263_RTP)
};
PLUGIN_NAME = "H.263 Encoder";
|
Methods Summary |
---|
public synchronized void | close()
// System.out.println("[h263Encoder:close]");
if (encodeControl != null)
encodeControl.close();
closeNativeEncoder();
super.close();
| private synchronized void | closeNative()
closeNativeEncoder();
| private native boolean | closeNativeEncoder()
| private native boolean | encodeFrameNative(javax.media.Buffer in, javax.media.Buffer out)
| protected void | finalize()
if (encodeControl != null) {
encodeControl.frame.dispose();
encodeControl = null;
}
| public java.lang.Object[] | getControls()
if (controls==null) {
controls=new Control[8];
controls[0]=new H263Adapter(this, false, false,false,false,false,0,1000,false);
controls[1]=new BitRateAdapter(this,useBitRate,minBitRate,maxBitRate,true);
controls[2]=new KeyFrameAdapter(this,iFramePeriod,true);
controls[3]=new QualityAdapter(this,1.0F,0.0F,1.0F,false,true);
controls[4]=new FrameRateAdapter(this,targetFrameRate,
sourceFrameRate/3,
sourceFrameRate,true);
controls[5]=new FrameProcessingAdapter(this);
controls[6]=new PacketSizeAdapter(this,targetOutputLength,true);
encodeControl = new EncodeControl(controls);
controls[7]= encodeControl;
}
return (Object[])controls;
| protected javax.media.Format[] | getMatchingOutputFormats(javax.media.Format in)
VideoFormat ivf = (VideoFormat) in;
Dimension inSize = ivf.getSize();
if (inSize==null)
return null;
videoWidth = inSize.width;
videoHeight = inSize.height;
// Amith - allow only default frame rate
supportedOutputFormats= new VideoFormat[2];
for (int i=0;i<2;) {
float useFrameRate=ivf.getFrameRate();
if (i==2)
useFrameRate /= 2.0F;
if (i==4)
useFrameRate /= 3.0F;
supportedOutputFormats[i++]=
new VideoFormat (
VideoFormat.H263,
new Dimension(inSize),
Format.NOT_SPECIFIED,
Format.byteArray,
useFrameRate);
supportedOutputFormats[i++]=
new VideoFormat ( //Hagai
VideoFormat.H263_RTP,
new Dimension(inSize),
Format.NOT_SPECIFIED,
Format.byteArray,
useFrameRate);
}
return supportedOutputFormats;
| protected void | initEncoder()
if (maxOutputLength != outputFormat.getMaxDataLength() ) {
VideoFormat f=outputFormat;
outputFormat = new VideoFormat(f.getEncoding(),f.getSize(),maxOutputLength,Format.byteArray,f.getFrameRate());
// System.out.println("of "+outputFormat);
}
/*
System.out.println("[h263Encoder:initEncoder]");
System.out.println("nativeFormat="+ nativeFormat);
System.out.println("sourceFrameRate="+ sourceFrameRate);
System.out.println("targetFrameRate="+ targetFrameRate);
System.out.println("useBitRate="+ useBitRate);
System.out.println("iFramePeriod="+ iFramePeriod);
System.out.println("maxOutputLength="+ maxOutputLength);
System.out.println("targetOutputLength="+ targetOutputLength);
System.out.println("useRTP="+useRtp);
*/
closeNative();
// System.out.println("[h263Encoder:initEncoder] : closed");
// initNativeEncoder(nativeFormat,useRtp);
if (useRtp)
initNativeEncoder(nativeFormat,
targetOutputLength, //MTUPacketSize
sourceFrameRate,
targetFrameRate,
useBitRate, //targetBitRate,
iFramePeriod );//IFramePeriod
else
initNativeEncoder(nativeFormat,
0, // "No RTP"
sourceFrameRate,//sourceFrameRate,
targetFrameRate,//targetFrameRate,
useBitRate, //targetBitRate,
iFramePeriod);//IFramePeriod
// System.out.println("[h263Encoder:initEncoder] : done");
| private native boolean | initNativeEncoder(int nativeFormat, int MTUPacketSize, float sourceFrameRate, float targetFrameRate, int targetBitRate, int IFramePeriod)
| public void | open()
// Validate sizes here.
// Native format
//
// |FRAME FORMAT width height image_format |
// |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
// |SQCIF 128 96 0 |
// |QCIF (PAL) 176 144 1 |
// |CIF (PAL) 352 288 2 |
///===add support for non standard frame size here==
if ( (videoWidth==128) && (videoHeight==96 ) ) {
nativeFormat=0;
} else if ( (videoWidth==176) && (videoHeight==144) ) {
nativeFormat=1;
} else if ( (videoWidth==352) && (videoHeight==288) ) {
nativeFormat=2;
} else {
Log.error("Class: " + this);
Log.error(" can only encode in sizes: 128x96, 176x144, 352x288.");
throw new ResourceUnavailableException("could not load jmvh263");
}
try {
JMFSecurityManager.loadLibrary("jmutil");
JMFSecurityManager.loadLibrary("jmh263enc");
//initFrame();
// initEncoder();
super.open();
if (encodeControl != null)
encodeControl.open(controls);
return;
}
catch (Throwable e) {
System.out.println(e);
}
//System.out.println("[h263encoder::open]could not load jmvh263");
throw new ResourceUnavailableException("could not load jmvh263");
| public synchronized int | process(javax.media.Buffer inputBuffer, javax.media.Buffer outputBuffer)
if (!initCompleted) {
// System.out.println("init encoder");
initCompleted=true;
initEncoder();
}
// Drop frame when necessary.
if (okToDrop && dropFrame) {
dropFrame = false;
outputBuffer.setDiscard(true);
if (settingsChanged)
reset();
return BUFFER_PROCESSED_OK;
}
okToDrop = false;
// System.out.println("[h263Encoder:process]");
if ( frameDone==true) {
// System.out.println(frame2skip);
frame2skip++;
if (frame2skip!=frameDecimation) {
updateOutput(outputBuffer,outputFormat, 0 , 0);
// outputBuffer.setDiscard(true);
return OUTPUT_BUFFER_NOT_FILLED;
}
frame2skip=0;
if (!checkInputBuffer(inputBuffer) ) {
return BUFFER_PROCESSED_FAILED;
}
if (isEOM(inputBuffer) ) {
propagateEOM(outputBuffer);
okToDrop = true;
if (settingsChanged)
reset();
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();
if (outMaxLength < MAX_RTP_MTU)
outMaxLength = MAX_RTP_MTU;
byte[] inData =(byte[]) inputBuffer.getData();
byte[] outData = validateByteArraySize(outputBuffer,outMaxLength );
boolean ret = encodeFrameNative(inputBuffer,outputBuffer);
// if (frameDone == false)
// System.out.println("[NativeEncoder:process] tr=" +tr + " outputLength= "+ outputLength + " timeStamp=" + inputBuffer.getTimeStamp() );
if (outputLength>=0)
outputBuffer.setLength(outputLength);
// update the output buffer fileds that are needed within the RTP header.
if (useRtp) {
outputBuffer.setSequenceNumber(sequenceNumber);
sequenceNumber++;
// RTPHeader header = (RTPHeader)outputBuffer.getHeader(); // this should have been done elsewhere ??
// if (null == header)
// header = new RTPHeader();
if (true == frameDone) {
timeStamp = inputBuffer.getTimeStamp();
// The above libe should be repaced with the line bellow if there is a possibility that the input
// Buffer does not have a timeStamp
// timeStamp += ((long)((tr-prevTr)&0x000000ff))*deltaFrames;
prevTr= tr;
int flags = outputBuffer.getFlags();
flags |= Buffer.FLAG_RTP_MARKER;
outputBuffer.setFlags(flags);
}
else {
}
// No need to set the time stamp.
//outputBuffer.setTimeStamp(timeStamp);
} else { // set key frame for intra frames
int flags = outputBuffer.getFlags();
if (!interFlag)
flags |= Buffer.FLAG_KEY_FRAME;
else
flags &= ~Buffer.FLAG_KEY_FRAME;
outputBuffer.setFlags(flags);
}
// note that encoder update output length
updateOutput(outputBuffer,outputFormat, outputBuffer.getLength() , 0);
// Amith - added this because outputFormat is defined in both BasicCodec
// and VideoCodec
outputBuffer.setFormat(outputFormat);
if (true == frameDone)
if (outputLength !=-1) {
okToDrop = true;
if (settingsChanged)
reset();
return BUFFER_PROCESSED_OK;
} else {
// System.out.println("[NativeEncoder:process]Last Gob Does not fit intop MTU");
return (OUTPUT_BUFFER_NOT_FILLED);
}
else
if (outputLength ==-1) { // a gob doesn't fit in an MTU
// System.out.println("[NativeEncoder:process] A gob doesn't fit in an MTU");
return (INPUT_BUFFER_NOT_CONSUMED|OUTPUT_BUFFER_NOT_FILLED);
}
else
return INPUT_BUFFER_NOT_CONSUMED;
| public final synchronized void | reset()
// System.out.println("[h263Encoder:reset]");
initEncoder();
settingsChanged = false;
| private native boolean | setFramesBehind(int numOfFrames)
| public javax.media.Format | setInputFormat(javax.media.Format format)
YUVFormat ivf = (YUVFormat) super.setInputFormat(format);
if (ivf==null)
return null;
Dimension inSize = ivf.getSize();
if (inSize==null)
return null;
if (ivf.getOffsetU() > ivf.getOffsetV())
return null;
videoWidth = inSize.width;
videoHeight = inSize.height;
sourceFrameRate=ivf.getFrameRate();
deltaFrames = (long) (1000000.0/ivf.getFrameRate()); // in Nano Seconds
if (opened) {
VideoFormat newOut;
newOut =
new VideoFormat (
outputFormat.getEncoding(),
new Dimension(inSize),
Format.NOT_SPECIFIED,
Format.byteArray,
ivf.getFrameRate());
close();
setOutputFormat(newOut);
try {
open();
} catch (ResourceUnavailableException re) {
return null;
}
}
return format;
| public javax.media.Format | setOutputFormat(javax.media.Format format)Hagai
overides VideoCodec.setOutputFormat in order to init RTP variables
VideoFormat f = (VideoFormat)super.setOutputFormat(format);
if (f.getMaxDataLength() == Format.NOT_SPECIFIED) {
if (f.getEncoding().equals(VideoFormat.H263_RTP)) {
useRtp = true;
maxOutputLength = MAX_RTP_MTU;
targetOutputLength = DEFAULT_RTP_MTU;
} else {
useRtp = false;
maxOutputLength = DEFAULT_MAX_OUTPUT_LENGTH;
targetOutputLength = DEFAULT_MAX_OUTPUT_LENGTH;
}
f = new VideoFormat(f.getEncoding(),f.getSize(),maxOutputLength,Format.byteArray,f.getFrameRate());
targetFrameRate=f.getFrameRate();
frameDecimation= (int)(sourceFrameRate/targetFrameRate);
useBitRate = (int) ((targetFrameRate * f.getSize().width *
f.getSize().height) / 5);
f = (VideoFormat)super.setOutputFormat(f);
}
return f; // How do we define who is responsible for initiating the MTU
| private native boolean | setQuality(float quality)
| protected void | videoResized()
// System.out.println("[h263Encoder:videoResized]");
initEncoder();
|
|