{
if (!filterGraph.isTrackEnabled(trackNumber))
return; // this track is disabled, nothing to do.
final Node penultimateNode = filterGraph.getBeforeTail(trackNumber);
boolean first = true;
boolean inputEOM = false; // set to true when the input buffer reaches EOM, which may be before the last buffer in the chain reaches EOM.
while (true)
{
if (isClosing())
return;
final int flags;
if (first)
flags = firstFlags; // if firstFlags == FilterGraph.SUPPRESS_TRACK_READ, first frame has already been read, only needs redisplay
else if (inputEOM)
flags = FilterGraph.SUPPRESS_TRACK_READ;
else
flags = FilterGraph.PROCESS_DEFAULT;
Buffer b = readAndProcessNextFrame(flags);
if (isClosing())
return;
if (first)
{ first = false;
}
if (b.isEOM())
inputEOM = true; // we continue processing, however, until the final buffer in the chain gets EOM.
// this is needed to handle the case where there is residual data in the codecs.
//TODO: how close is this to what JMF does? How does JMF handle this?
// if we don't do this, the effect is that codecs that are not 1:1 in terms of buffers will have any
// data buffered up in the codecs cut off.
if (b.isDiscard())
continue;
if (!(penultimateNode instanceof RendererNode) && !(penultimateNode instanceof MuxNode))
{
// we need to sleep based on the time in the processed data, not the input data.
// if the graph goes demux->renderer, then the output buffer of the demux,
// which is set to b above, is what we use to check.
b = penultimateNode.getOutputBuffer(0);
// TODO: this can cause a NPE below if b is null (not sure how it could be null)
if (b == null)
continue; // this can be null if it has not been set yet, if codecs earlier in the chain have been
// returning INPUT_BUFFER_NOT_CONSUMED or OUTPUT_BUFFER_NOT_FILLED.