BasicFilterModulepublic class BasicFilterModule extends BasicModule BasicFilterModule is a module which is not threaded and have one InputConnector and one OutputConnector.
It receives data from its input connector, pass the data to the level 3 plugIn codec and put the
result in the OutputConnector.
BasicFilterModule can be either Push or Pull driven.
The plugIn codec might be media decoder, media encoder, effect etc. |
Fields Summary |
---|
protected Codec | codec | protected InputConnector | ic | protected OutputConnector | oc | protected FrameProcessingControl | frameControl | protected float | curFramesBehind | protected float | prevFramesBehind | protected Frame | controlFrame | protected final boolean | VERBOSE_CONTROL | protected Buffer | storedInputBuffer | protected Buffer | storedOutputBuffer | protected boolean | readPendingFlag | protected boolean | writePendingFlag | private boolean | failed | private boolean | markerSet | private Object | lastHdr |
Constructors Summary |
---|
public BasicFilterModule(Codec c)
ic=new BasicInputConnector();
registerInputConnector("input",ic);
oc=new BasicOutputConnector();
registerOutputConnector("output",oc);
setCodec(c);
protocol = Connector.ProtocolPush;
Object control = c.getControl("javax.media.control.FrameProcessingControl");
if (control instanceof FrameProcessingControl)
frameControl = (FrameProcessingControl) control;
|
Methods Summary |
---|
public void | doClose()
if (codec != null) {
codec.close();
}
if (controlFrame!=null) {
controlFrame.dispose();
controlFrame=null;
}
/*
if (monitorFrame != null)
monitorFrame.dispose();
*/
| public boolean | doPrefetch()
return super.doPrefetch();
| public boolean | doRealize()
if (codec != null) {
try {
codec.open();
if (VERBOSE_CONTROL) {
controlFrame=new java.awt.Frame(codec.getName()+" Control");
controlFrame.setLayout(new com.sun.media.controls.VFlowLayout(1));
controlFrame.add(new Label(codec.getName()+" Control",Label.CENTER) );
controlFrame.add(new Label( " "));
Control[] c=(Control[]) codec.getControls();
for (int i=0;i<c.length;i++) {
controlFrame.add(c[i].getControlComponent() );
}
controlFrame.pack();
controlFrame.show();
}
} catch (ResourceUnavailableException rue) {
return false;
}
}
return true;
| public javax.media.Codec | getCodec()
return codec;
| public java.lang.Object | getControl(java.lang.String s)
return codec.getControl(s);
| public java.lang.Object[] | getControls()
return codec.getControls();
| public boolean | isThreaded()
if ( (getProtocol() == Connector.ProtocolSafe) )
return true;
return false;
| public void | process()
// System.out.println("Filter.process: " + codec);
Buffer inputBuffer, outputBuffer;
do {
if (readPendingFlag)
inputBuffer = storedInputBuffer;
else {
Format incomingFormat;
inputBuffer = ic.getValidBuffer();
incomingFormat = inputBuffer.getFormat();
if (incomingFormat == null) {
// Something's weird, we'll just assume it's the previous
// format.
incomingFormat = ic.getFormat();
inputBuffer.setFormat(incomingFormat);
}
if (incomingFormat != ic.getFormat() &&
incomingFormat != null &&
!incomingFormat.equals(ic.getFormat()) &&
!inputBuffer.isDiscard()) {
// The format is changed mid-stream!
if (writePendingFlag) {
// Discard the pending output buffer.
storedOutputBuffer.setDiscard(true);
oc.writeReport();
writePendingFlag = false;
}
// Attempt to re-initialize the plugin codec.
// Bail out if failed.
if (!reinitCodec(inputBuffer.getFormat())) {
// Failed.
inputBuffer.setDiscard(true);
ic.readReport();
failed = true;
// Just signal an internal error for now.
if (moduleListener != null)
moduleListener.formatChangedFailure(this,
ic.getFormat(), inputBuffer.getFormat());
return;
}
Format oldFormat = ic.getFormat();
ic.setFormat(inputBuffer.getFormat());
if (moduleListener != null)
moduleListener.formatChanged(this, oldFormat,
inputBuffer.getFormat());
}
// The marker flag needs to be handle more delicately.
// For codec that takes multiple input buffers to generate
// a single output buffer (e.g. RTP depackizer), if there's
// one input buffer that has the market flag set, the
// corresponding output buffer will need to have the
// marker flag set.
if ((inputBuffer.getFlags() & Buffer.FLAG_SYSTEM_MARKER) != 0) {
markerSet = true;
}
if (PlaybackEngine.DEBUG && inputBuffer != null)
jmd.moduleIn(this, 0, inputBuffer, true);
}
if (writePendingFlag)
outputBuffer = storedOutputBuffer;
else {
outputBuffer = oc.getEmptyBuffer();
if (outputBuffer != null) {
if (PlaybackEngine.DEBUG)
jmd.moduleOut(this, 0, outputBuffer, true);
outputBuffer.setLength(0);
outputBuffer.setOffset(0);
lastHdr = outputBuffer.getHeader();
}
}
// Copy from input to output.
outputBuffer.setTimeStamp(inputBuffer.getTimeStamp());
outputBuffer.setDuration(inputBuffer.getDuration());
outputBuffer.setSequenceNumber(inputBuffer.getSequenceNumber());
outputBuffer.setFlags(inputBuffer.getFlags());
outputBuffer.setHeader(inputBuffer.getHeader());
// Check if we are in the resetted state.
if (resetted) {
// Check if the input buffer contains the zero-length
// flush flag. If so, we are almost done.
if ((inputBuffer.getFlags() & Buffer.FLAG_FLUSH) != 0) {
codec.reset();
resetted = false;
}
// In the resetted state, we won't process any of the
// data. We'll just return the buffers unprocessed.
readPendingFlag = writePendingFlag = false;
ic.readReport();
oc.writeReport();
return;
}
if (failed || inputBuffer.isDiscard()) {
// Reset the marker flag.
if (markerSet) {
outputBuffer.setFlags(outputBuffer.getFlags() &
~Buffer.FLAG_SYSTEM_MARKER);
markerSet = false;
}
// If the discard flag from the upstream module
// is set, it has probably dropped a frame. The
// curFramesBehind counter should be resetted.
// Otherwise, too many frames will be dropped.
curFramesBehind = 0;
ic.readReport();
// Propagate the discard flag downstream.
// This is needed so the renderer can keep track of
// a correct frame count even for the discarded frames.
if (!writePendingFlag)
oc.writeReport();
return;
}
if (frameControl != null && curFramesBehind != prevFramesBehind &&
(inputBuffer.getFlags() & Buffer.FLAG_NO_DROP) == 0) {
frameControl.setFramesBehind(curFramesBehind);
prevFramesBehind = curFramesBehind;
}
int rc = 0;
try {
rc = codec.process(inputBuffer , outputBuffer);
} catch (Throwable e) {
Log.dumpStack(e);
if (moduleListener != null)
moduleListener.internalErrorOccurred(this);
}
if (PlaybackEngine.TRACE_ON && !verifyBuffer(outputBuffer)) {
System.err.println("verify buffer failed: " + codec);
Thread.dumpStack();
if (moduleListener != null)
moduleListener.internalErrorOccurred(this);
}
if ((rc & PlugIn.PLUGIN_TERMINATED) != 0) {
failed = true;
if (moduleListener != null)
moduleListener.pluginTerminated(this);
readPendingFlag = writePendingFlag = false;
ic.readReport();
oc.writeReport();
return;
}
if (curFramesBehind > 0f && outputBuffer.isDiscard()) {
// One frame has been dropped. We'll need to update
// the framesBehind count.
// If we don't do that, we run into trouble that the
// renderer sometimes cannot update the frames behind
// count immediately (thread scheduling may prefer this
// thread to the rendering thread). As a result, the
// decoder will keep dropping frames without a correct
// frame count from the renderer.
curFramesBehind -= 1.0f;
if (curFramesBehind < 0)
curFramesBehind = 0f;
// We'll also need to propagate the discard flag
// downstream just so the the downstream module can
// update their framesbehind info accordingly. To
// do that, we override the plugin's return value to
// make sure that OUTPUT_BUFFER_NOT_FILLED is not used.
rc = rc & ~codec.OUTPUT_BUFFER_NOT_FILLED;
}
if ( (rc & codec.BUFFER_PROCESSED_FAILED) != 0 ) {
outputBuffer.setDiscard(true);
// Reset the marker flag.
if (markerSet) {
outputBuffer.setFlags(outputBuffer.getFlags() &
~Buffer.FLAG_SYSTEM_MARKER);
markerSet = false;
}
if (PlaybackEngine.DEBUG) jmd.moduleIn(this, 0, inputBuffer, false);
ic.readReport();
if (PlaybackEngine.DEBUG) jmd.moduleOut(this, 0, outputBuffer, false);
oc.writeReport();
readPendingFlag = writePendingFlag = false;
return;
}
// Do not propagate the EOM flag if the input buffer is
// not fully consumed or the output buffer is not fully filled.
if ( outputBuffer.isEOM() &&
((rc & codec.INPUT_BUFFER_NOT_CONSUMED) != 0 ||
(rc & codec.OUTPUT_BUFFER_NOT_FILLED) != 0) ) {
// We are not quite done yet, so the output buffer
// is not set to EOM.
outputBuffer.setEOM(false);
}
if ( (rc & codec.OUTPUT_BUFFER_NOT_FILLED) != 0 ) {
writePendingFlag=true;// next call to getEmptyBuffer will return the same Buffer
storedOutputBuffer=outputBuffer;
} else {
if (PlaybackEngine.DEBUG) jmd.moduleOut(this, 0, outputBuffer, false);
if (markerSet) {
outputBuffer.setFlags(outputBuffer.getFlags() |
Buffer.FLAG_SYSTEM_MARKER);
markerSet = false;
}
/*
if (outputBuffer.getFormat() instanceof RGBFormat)
monitorCheck(outputBuffer);
*/
oc.writeReport();
writePendingFlag=false;
}
if ( ((rc & codec.INPUT_BUFFER_NOT_CONSUMED) != 0 ||
(inputBuffer.isEOM() && !outputBuffer.isEOM())) ) {
readPendingFlag=true; // next call to getValidBuffer will return the same Buffer
storedInputBuffer=inputBuffer;
} else {
if (PlaybackEngine.DEBUG) jmd.moduleIn(this, 0, inputBuffer, false);
inputBuffer.setHeader(lastHdr);
ic.readReport();
readPendingFlag=false;
}
} while (readPendingFlag);
| protected boolean | reinitCodec(javax.media.Format input)A new input format has been detected, we'll check if the existing
codec can handle it. Otherwise, we'll try to re-create a new codec
to handle it.
// Query the existing plugin to see if it supports the new input.
if (codec != null) {
if (codec.setInputFormat(input) != null) {
// Fine, the existing codec still works.
return true;
}
// close the previous codec.
codec.close();
codec = null;
}
// Find a new codec that supports the input
Codec c;
if ((c = SimpleGraphBuilder.findCodec(input, null, null, null)) == null)
return false;
setCodec(c);
return true;
| public boolean | setCodec(java.lang.String codec)sets the plugIn codec of this filter.
return true;
| public boolean | setCodec(javax.media.Codec codec) // patch until codecmanager exists
this.codec=codec;
return true;
| public void | setFormat(com.sun.media.Connector c, javax.media.Format f)
if (c == ic) {
// Input Connector
if (codec != null)
codec.setInputFormat(f);
} else if (c == oc) {
if (codec != null)
codec.setOutputFormat(f);
}
| protected void | setFramesBehind(float framesBehind)
curFramesBehind = framesBehind;
|
|