Package rtp.rtptransmit.videotransmit

Source Code of rtp.rtptransmit.videotransmit.VideoTransmit$StateListener

package rtp.rtptransmit.videotransmit;
/*
* @(#)VideoTransmit.java  1.7 01/03/13
*
* Copyright (c) 1999-2001 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/

import java.awt.Dimension;
import java.io.IOException;

import javax.media.Codec;
import javax.media.Control;
import javax.media.Controller;
import javax.media.ControllerClosedEvent;
import javax.media.ControllerEvent;
import javax.media.ControllerListener;
import javax.media.DataSink;
import javax.media.Format;
import javax.media.Manager;
import javax.media.MediaException;
import javax.media.MediaLocator;
import javax.media.NoProcessorException;
import javax.media.Owned;
import javax.media.Player;
import javax.media.Processor;
import javax.media.control.QualityControl;
import javax.media.control.TrackControl;
import javax.media.format.VideoFormat;
import javax.media.protocol.ContentDescriptor;
import javax.media.protocol.DataSource;

public class VideoTransmit {

    // Input MediaLocator
    // Can be a file or http or capture source
    private MediaLocator locator;
    private String ipAddress;
    private String port;

    private Processor processor = null;
    private DataSink  rtptransmitter = null;
    private DataSource dataOutput = null;
   
    public VideoTransmit(MediaLocator locator,
       String ipAddress,
       String port) {
 
  this.locator = locator;
  this.ipAddress = ipAddress;
  this.port = port;
    }

    /**
     * Starts the transmission. Returns null if transmission started ok.
     * Otherwise it returns a string with the reason why the setup failed.
     */
    public synchronized String start() {
  String result;

  // Create a processor for the specified media locator
  // and program it to output JPEG/RTP
  result = createProcessor();
  if (result != null)
      return result;

  // Create an RTP session to transmit the output of the
  // processor to the specified IP address and port no.
  result = createTransmitter();
  if (result != null) {
      processor.close();
      processor = null;
      return result;
  }

  // Start the transmission
  processor.start();
 
  return null;
    }

    /**
     * Stops the transmission if already started
     */
    public void stop() {
  synchronized (this) {
      if (processor != null) {
    processor.stop();
    processor.close();
    processor = null;
    rtptransmitter.close();
    rtptransmitter = null;
      }
  }
    }

    private String createProcessor() {
  if (locator == null)
      return "Locator is null";

  DataSource ds;
  DataSource clone;

  try {
      ds = Manager.createDataSource(locator);
  } catch (Exception e) {
      return "Couldn't create DataSource";
  }

  // Try to create a processor to handle the input media locator
  try {
      processor = Manager.createProcessor(ds);
  } catch (NoProcessorException npe) {
      return "Couldn't create processor";
  } catch (IOException ioe) {
      return "IOException creating processor";
  }

  // Wait for it to configure
  boolean result = waitForState(processor, Processor.Configured);
  if (result == false)
      return "Couldn't configure processor";

  // Get the tracks from the processor
  TrackControl [] tracks = processor.getTrackControls();

  // Do we have atleast one track?
  if (tracks == null || tracks.length < 1)
      return "Couldn't find tracks in processor";

  boolean programmed = false;

  // Search through the tracks for a video track
  for (int i = 0; i < tracks.length; i++) {
      Format format = tracks[i].getFormat();
      if tracks[i].isEnabled() &&
      format instanceof VideoFormat &&
      !programmed) {
   
    // Found a video track. Try to program it to output JPEG/RTP
    // Make sure the sizes are multiple of 8's.
    Dimension size = ((VideoFormat)format).getSize();
    float frameRate = ((VideoFormat)format).getFrameRate();
    int w = (size.width % 8 == 0 ? size.width :
        (int)(size.width / 8) * 8);
    int h = (size.height % 8 == 0 ? size.height :
        (int)(size.height / 8) * 8);
    VideoFormat jpegFormat = new VideoFormat(VideoFormat.JPEG_RTP,
               new Dimension(w, h),
               Format.NOT_SPECIFIED,
               Format.byteArray,
               frameRate);
    tracks[i].setFormat(jpegFormat);
    System.err.println("Video transmitted as:");
    System.err.println("  " + jpegFormat);
    // Assume succesful
    programmed = true;
      } else
    tracks[i].setEnabled(false);
  }

  if (!programmed)
      return "Couldn't find video track";

  // Set the output content descriptor to RAW_RTP
  ContentDescriptor cd = new ContentDescriptor(ContentDescriptor.RAW_RTP);
  processor.setContentDescriptor(cd);

  // Realize the processor. This will internally create a flow
  // graph and attempt to create an output datasource for JPEG/RTP
  // video frames.
  result = waitForState(processor, Controller.Realized);
  if (result == false)
      return "Couldn't realize processor";

  // Set the JPEG quality to .5.
  setJPEGQuality(processor, 0.5f);

  // Get the output data source of the processor
  dataOutput = processor.getDataOutput();
  return null;
    }

    // Creates an RTP transmit data sink. This is the easiest way to create
    // an RTP transmitter. The other way is to use the RTPSessionManager API.
    // Using an RTP session manager gives you more control if you wish to
    // fine tune your transmission and set other parameters.
    private String createTransmitter() {
  // Create a media locator for the RTP data sink.
  // For example:
  //    rtp://129.130.131.132:42050/video
  String rtpURL = "rtp://" + ipAddress + ":" + port + "/video";
  MediaLocator outputLocator = new MediaLocator(rtpURL);

  // Create a data sink, open it and start transmission. It will wait
  // for the processor to start sending data. So we need to start the
  // output data source of the processor. We also need to start the
  // processor itself, which is done after this method returns.
  try {
      rtptransmitter = Manager.createDataSink(dataOutput, outputLocator);
      rtptransmitter.open();
      rtptransmitter.start();
      dataOutput.start();
  } catch (MediaException me) {
      return "Couldn't create RTP data sink";
  } catch (IOException ioe) {
      return "Couldn't create RTP data sink";
  }
 
  return null;
    }


    /**
     * Setting the encoding quality to the specified value on the JPEG encoder.
     * 0.5 is a good default.
     */
    void setJPEGQuality(Player p, float val) {

  Control cs[] = p.getControls();
  QualityControl qc = null;
  VideoFormat jpegFmt = new VideoFormat(VideoFormat.JPEG);

  // Loop through the controls to find the Quality control for
   // the JPEG encoder.
  for (int i = 0; i < cs.length; i++) {

      if (cs[i] instanceof QualityControl &&
    cs[i] instanceof Owned) {
    Object owner = ((Owned)cs[i]).getOwner();

    // Check to see if the owner is a Codec.
    // Then check for the output format.
    if (owner instanceof Codec) {
        Format fmts[] = ((Codec)owner).getSupportedOutputFormats(null);
        for (int j = 0; j < fmts.length; j++) {
      if (fmts[j].matches(jpegFmt)) {
          qc = (QualityControl)cs[i];
              qc.setQuality(val);
          System.err.println("- Setting quality to " +
          val + " on " + qc);
          break;
      }
        }
    }
    if (qc != null)
        break;
      }
  }
    }


    /****************************************************************
     * Convenience methods to handle processor's state changes.
     ****************************************************************/
   
    private Integer stateLock = new Integer(0);
    private boolean failed = false;
   
    Integer getStateLock() {
  return stateLock;
    }

    void setFailed() {
  failed = true;
    }
   
    private synchronized boolean waitForState(Processor p, int state) {
  p.addControllerListener(new StateListener());
  failed = false;

  // Call the required method on the processor
  if (state == Processor.Configured) {
      p.configure();
  } else if (state == Processor.Realized) {
      p.realize();
  }
 
  // Wait until we get an event that confirms the
  // success of the method, or a failure event.
  // See StateListener inner class
  while (p.getState() < state && !failed) {
      synchronized (getStateLock()) {
    try {
        getStateLock().wait();
    } catch (InterruptedException ie) {
        return false;
    }
      }
  }

  if (failed)
      return false;
  else
      return true;
    }

    /****************************************************************
     * Inner Classes
     ****************************************************************/

    class StateListener implements ControllerListener {

  public void controllerUpdate(ControllerEvent ce) {

      // If there was an error during configure or
      // realize, the processor will be closed
      if (ce instanceof ControllerClosedEvent)
    setFailed();

      // All controller events, send a notification
      // to the waiting thread in waitForState method.
      if (ce instanceof ControllerEvent) {
    synchronized (getStateLock()) {
        getStateLock().notifyAll();
    }
      }
  }
    }


    /****************************************************************
     * Sample Usage for VideoTransmit class
     ****************************************************************/
   
    public static void main(String [] args) {
  // We need three parameters to do the transmission
  // For example,
  //   java VideoTransmit file:/C:/media/test.mov  129.130.131.132 42050
 
  if (args.length < 3) {
      System.err.println("Usage: VideoTransmit <sourceURL> <destIP> <destPort>");
      System.exit(-1);
  }
 
  // Create a video transmit object with the specified params.
  VideoTransmit vt = new VideoTransmit(new MediaLocator(args[0]),
               args[1],
               args[2]);
  // Start the transmission
  String result = vt.start();

  // result will be non-null if there was an error. The return
  // value is a String describing the possible error. Print it.
  if (result != null) {
      System.err.println("Error : " + result);
      System.exit(0);
  }

  System.err.println("Start transmission for 60 seconds...");
 
  // Transmit for 60 seconds and then close the processor
  // This is a safeguard when using a capture data source
  // so that the capture device will be properly released
  // before quitting.
  // The right thing to do would be to have a GUI with a
  // "Stop" button that would call stop on VideoTransmit
  try {
      Thread.sleep(60000);
  } catch (InterruptedException ie) {
  }

  // Stop the transmission
  vt.stop();

  System.err.println("...transmission ended.");
 
  System.exit(0);
    }
}

TOP

Related Classes of rtp.rtptransmit.videotransmit.VideoTransmit$StateListener

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.