Package net.sf.fmj.filtergraph

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

/**
*
*/
package net.sf.fmj.filtergraph;

import javax.media.Buffer;
import javax.media.Clock;
import javax.media.Format;
import javax.media.PlugInManager;
import javax.media.Prefetchable;
import javax.media.Renderer;
import javax.media.ResourceUnavailableException;
import javax.media.Time;

import net.sf.fmj.media.SleepHelper;

/**
* A node in a filter graph for a Renderer.  dest is empty.
* @author Ken Larson
*
*/
public class RendererNode extends Node
  private final Renderer renderer;
  private boolean prefetched;    // Only for Renderers implementing Prefetchable. 
  private final SleepHelper sleepHelper = new SleepHelper();
 
  public RendererNode(Renderer renderer, Format inputFormat)
  {
    super(renderer, 1, 0);
    setInputPin(0, new InputPin(this));
    this.renderer = renderer;
    getInputPin(0).setFormat(inputFormat);
  }
 
 
  @Override
  public int getPlugInType()
  {
    return PlugInManager.RENDERER;
  }

  @Override
  Format setPlugInInputFormat(InputPin pin, Format format)
  {
    return renderer.setInputFormat(format);
  }
 
  @Override
  Format setPlugInOutputFormat(OutputPin pin, Format format)
  {  throw new UnsupportedOperationException();
  }
 
  @Override
  public Node duplicate()
  {
    return propagateDuplicate(new RendererNode(getRenderer(), getInputFormat()));
   
  }

  public Renderer getRenderer()
  {
    return renderer;
  }

  @Override
  public Format getInputFormat()
  {
    return getInputPin(0).getFormat();
  }

  public void setPrefetched(boolean prefetched)
  {
    this.prefetched = prefetched;
  }

  public boolean isPrefetched()
  {
    return prefetched;
  }

  @Override
  public void open() throws ResourceUnavailableException
  {
    super.open();
    sleepHelper.reset();
  }
 
  @Override
  public void stop()
  {
    getRenderer().stop();
    sleepHelper.reset();
   
  }

  @Override
  public void start()
  {
    sleepHelper.reset();
    getRenderer().start();
   
  }

  @Override
  public int process(final Buffer input, final int sourceTrackNumber, final int destTrackNumber, final int flags)
  {
    final Renderer renderer = getRenderer();
    if (input.getFormat() == null)
      input.setFormat(getInputFormat())// TODO: is this right?
   
    if (renderer instanceof Prefetchable)
    {
      // TODO: where should this be done?  In the Handler's prefetch()?
      final Prefetchable rendererAsPrefetchable = (Prefetchable) renderer;
      if (!isPrefetched() && rendererAsPrefetchable.isPrefetched())
      {
        if (renderer instanceof Clock)
        {
          final Clock rendererAsClock = (Clock) renderer;
          // TODO: what do we set the time to be?
          rendererAsClock.syncStart(new Time(rendererAsClock.getMediaNanoseconds()));
        }
        setPrefetched(true);
      }
    }
   
    {
      int processResult;
     
      // TODO: the caller should take care of this loop.
      do
      {
        int oldOffset = input.getOffset();

                // mgodehardt: sleeping causes audio streams to get hipcups
        // calculate and sleep any sleep needed:
              /*try
              {  sleepHelper.sleep(input.getTimeStamp());
        }
              catch (InterruptedException e)
        {
          logger.log(Level.WARNING, "" + e, e);
          return Renderer.BUFFER_PROCESSED_FAILED;
        }*/
            
       
        //long start = System.currentTimeMillis();
        processResult = renderer.process(input)// TODO: check return code
        //long stop = System.currentTimeMillis();
        //System.out.println("Renderer process took " + (stop - start) + " ms");
       
        if (processResult == Renderer.INPUT_BUFFER_NOT_CONSUMED)
        {
          logger.fine("processResult == Renderer.INPUT_BUFFER_NOT_CONSUMED");
          logger.fine("oldOffset = " + oldOffset);
          logger.fine("newoffset = " + input.getOffset());
         
          break;
        }
       
        if (processResult != Renderer.BUFFER_PROCESSED_OK)
        {
          logger.warning("Renderer process result (loop): " + processResult);
        }
      }
      while (processResult == Renderer.INPUT_BUFFER_NOT_CONSUMED);
//       INPUT_BUFFER_NOT_CONSUMED: The input Buffer chunk was not fully consumed. The plug-in should update the offset + length fields of the Buffer. The plug-in will be called later with the same input Buffer.
     
      if (processResult != Renderer.BUFFER_PROCESSED_OK)
      {
        logger.warning("Renderer process result: " + processResult);
        return processResult;   // TODO: what do we do with the error?  set a flag in the buffer?
      }

    }
   
    return Renderer.BUFFER_PROCESSED_OK; 
   
  }
 
  @Override
  public void addDestLink(Link n)
  {
    throw new UnsupportedOperationException();
  }
 


}
TOP

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

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.