Package net.sf.fmj.filtergraph

Source Code of net.sf.fmj.filtergraph.FilterGraphProcessor

package net.sf.fmj.filtergraph;

import java.io.IOException;
import java.util.logging.Logger;

import javax.media.Buffer;
import javax.media.PlugIn;
import javax.media.ResourceUnavailableException;

import net.sf.fmj.utility.LoggerSingleton;

/**
* Execute functions on filter graphs.  Does not actually represent the graph itself, that
* would be simply a FilterGraphNode being used as a root.
* TODO: if a demux for example sets both discard and eom, what are the semantics?  It appears that
* we will discard the EOM.
* @author Ken Larson
*
*/
final class FilterGraphProcessor
{
  private static final Logger logger = LoggerSingleton.logger;

  private static final boolean TRACE = true;

  private FilterGraphProcessor()
  {  super();
  }

  public static Node getTail(Node n)
  {
    if (n == null) {
      return n;
    }
    while (n.getNumDestLinks() > 0)
      n = n.getDestLink(0).getDestNode()// TODO: this doesn't handle demuxs
    return n;
  }
 
  /**
   * Finds a penultimate node - one right before a mux or renderer.
   */
  public static Node getBeforeTail(Node n)
  {
    // TODO: this always follows the first link from any node.
    while (n.getNumDestLinks() > 0 && n.getDestLink(0).getDestNode().getNumDestLinks() > 0)
    {  n = n.getDestLink(0).getDestNode()// TODO: this doesn't handle demuxs
    }
    return n;
 
 
  public static void start(Node n) throws IOException
  {
    n.start();
   
    for (int i = 0; i < n.getNumDestLinks(); ++i)
    {  final Link destLink = n.getDestLink(i);
      if (destLink != null)
        start(destLink.getDestNode())// track doesn't matter for this.  TODO: prevent starting same node twice.
    }
 

  }
 
  public static void stop(Node n) throws IOException
  {
    n.stop();

    for (int i = 0; i < n.getNumDestLinks(); ++i)
    {  final Link destLink = n.getDestLink(i);
      if (destLink != null)
        stop(destLink.getDestNode())// track doesn't matter for this.  TODO: prevent starting same node twice.
    }
 

  }
 
 
  public static void open(Node n) throws ResourceUnavailableException
  {
    n.open();
   
    for (int i = 0; i < n.getNumDestLinks(); ++i)
    {  final Link destLink = n.getDestLink(i);
      if (destLink != null)
        open(destLink.getDestNode())// track doesn't matter for this.  TODO: prevent opening same node twice.
    }
 

  }
 
  // TODO: call this method during cleanup.
  public static void close(Node n) throws ResourceUnavailableException
  {
    n.close();
   
    for (int i = 0; i < n.getNumDestLinks(); ++i)
    {  final Link destLink = n.getDestLink(i);
      if (destLink != null)
        close(destLink.getDestNode())// track doesn't matter for this.  TODO: prevent closing same node twice.
    }
 

  }
 


  // flags for process
  public static final int PROCESS_DEFAULT     = 0;
  public static final int SUPPRESS_TRACK_READ   = 0x0001// used to be able to re-display a frame.  For example, when we first open a movie, we usually want to get the first frame to see how big it is
  /**
   * Process a graph starting with n
   * @param n
   * @param input the source buffer
   * sourceTrackNumber only used for demux, and destTrackNumber only used for mux
   */
  public static int process(final Node n, final Buffer input, final int sourceTrackNumber, final int destTrackNumber, final int flags)
  {
    //if (sourceTrackNumber < 0)
    //  throw new IllegalArgumentException();
    // EOM propagation needs to go all the way to renderer, that's what JMF does.
   
    int result = PlugIn.BUFFER_PROCESSED_OK;
   
    do
    {
//      if (result == PlugIn.INPUT_BUFFER_NOT_CONSUMED)
//      {
//        try
//        {
//          Thread.sleep(20);
//        } catch (InterruptedException e)
//        {
//          // TODO Auto-generated catch block
//          e.printStackTrace();
//        }
//      }
      result = n.process(input, sourceTrackNumber, destTrackNumber, flags);
      // TODO: sleep on retry??
     
      if (result != PlugIn.BUFFER_PROCESSED_OK && result != PlugIn.INPUT_BUFFER_NOT_CONSUMED) // TODO
      if (result == PlugIn.BUFFER_PROCESSED_FAILED)
          logger.warning("BUFFER_PROCESSED_FAILED: " + n.getPlugIn());
        return result;  // TODO: error code return?
      }
     
      for (int i = 0; i < n.getNumDestLinks(); ++i)
      { 
        if (n instanceof DemuxNode && sourceTrackNumber >= 0 && i != sourceTrackNumber)
        {  continue;
       
       
        final Link linkDest = n.getDestLink(i);
        if (linkDest != null)
        {  if (n.getOutputBuffer(i) == null)
            throw new NullPointerException("Buffer " + i + " is null, trackNumber=" + sourceTrackNumber + ", flags=" + flags);
          final Buffer b = n.getOutputBuffer(i);
          // TODO: what is the proper place to check for and/or propagate EOM/discard?
//          if (b.isEOM())
//            continue;
          if (b.isDiscard())
          { 
//            try
//            {
//              Thread.sleep(20);
//            } catch (InterruptedException e)
//            {
//              // TODO Auto-generated catch block
//              e.printStackTrace();
//            }
            continue;
          }
          //linkDest.getDestNode().process(b, -1, linkDest.getDestTrack(), flags);
          if (process(linkDest.getDestNode(), b, -1, linkDest.getDestPin().getTrack(), flags) == PlugIn.BUFFER_PROCESSED_FAILED)
          {  return PlugIn.BUFFER_PROCESSED_FAILED;
          }
        }
      }
    }
    while (result == PlugIn.INPUT_BUFFER_NOT_CONSUMED);
   

    return result;
   
  }
 

 
}
TOP

Related Classes of net.sf.fmj.filtergraph.FilterGraphProcessor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.