Link to home
Start Free TrialLog in
Avatar of qasitouch
qasitouchFlag for Pakistan

asked on

video not played using JMF while tramitting stream over RTP

I am using code to tranmit video using RTP using JMF and i am able to successfully get the video on client side

Code to send the  video over rtp
http://java.sun.com/javase/technologies/desktop/media/jmf/2.1.1/solutions/AVTransmit2.java

code to recieve video over rtp
http://java.sun.com/javase/technologies/desktop/media/jmf/2.1.1/solutions/AVReceive.html#source

My problem is i am not able to play video in AVTransmit2.java.
If i create a player using datasouce, eigther i get player already occupied or a black screen.

please help me running the video on Transmit side as well.


NOTE: i am using web cam for video source
Avatar of qasitouch
qasitouch
Flag of Pakistan image

ASKER

Below is my actuall class which i am using to transmit and play video on tranmitter side

package secure.tech.studio.app.device;

import java.awt.Component;
import java.awt.Dimension;
import java.io.IOException;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.util.Iterator;
import java.util.Vector;

import javax.media.CannotRealizeException;
import javax.media.CaptureDeviceInfo;
import javax.media.CaptureDeviceManager;
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.Format;
import javax.media.Manager;
import javax.media.MediaLocator;
import javax.media.NoPlayerException;
import javax.media.NoProcessorException;
import javax.media.NotRealizedError;
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;
import javax.media.protocol.PushBufferDataSource;
import javax.media.protocol.PushBufferStream;
import javax.media.rtp.RTPManager;
import javax.media.rtp.SendStream;
import javax.media.rtp.SessionAddress;
import javax.media.rtp.rtcp.SourceDescription;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

/**
 * @author Waqas Sadiq
 * @project securestudioutil
 * @date Dec 22, 2009
 */
public class ServerTransmision   extends JPanel{

      // Can be a file or http or capture source
      private MediaLocator locator;
      //            OR      
      //      if no web cam attached, otherwise comment below statement
      //    private MediaLocator locator = new MediaLocator("file:/C:/Clock.avi");

      private String ipAddress = "172.16.20.244"; //destination client IP
      private int portBase = 22222;

      private Processor processor = null;
      private RTPManager rtpMgrs[];
      private DataSource dataOutput = null;

      public ServerTransmision() {

            initialize();

      }

      /**
       * cature the media device and set the locator
       */
      private void initialize() {
            Vector devices = CaptureDeviceManager.getDeviceList(null);
            CaptureDeviceInfo cdi = null;
            for (Iterator i = devices.iterator(); i.hasNext();) {
                  cdi = (CaptureDeviceInfo) i.next();
                  if (cdi.getName().startsWith("vfw:"))
                        break;
            }

            if (locator == null) {
                  locator = cdi.getLocator();

            }

      }

      public ServerTransmision(MediaLocator locator, String ipAddress, String pb,
                  Format format) {

            this.locator = locator;
            this.ipAddress = ipAddress;
            Integer integer = Integer.valueOf(pb);
            if (integer != null)
                  this.portBase = integer.intValue();
      }

      /**
       * 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;

            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;
                        for (int i = 0; i < rtpMgrs.length; i++) {
                              rtpMgrs[i].removeTargets("Session ended.");
                              rtpMgrs[i].dispose();
                        }
                  }
            }
      }

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

            DataSource ds;
            DataSource clone;

            try {
            
                  ds = Manager.createDataSource(locator);
                  
                  //create player pop
                  createPlayer(Manager.createCloneableDataSource(ds));

            } 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";

            // Set the output content descriptor to RAW_RTP
            // This will limit the supported formats reported from
            // Track.getSupportedFormats to only valid RTP formats.
            ContentDescriptor cd = new ContentDescriptor(ContentDescriptor.RAW_RTP);
            processor.setContentDescriptor(cd);

            Format supported[];
            Format chosen;
            boolean atLeastOneTrack = false;

            // Program the tracks.
            for (int i = 0; i < tracks.length; i++) {
                  Format format = tracks[i].getFormat();
                  if (tracks[i].isEnabled()) {

                        supported = tracks[i].getSupportedFormats();

                        // We've set the output content to the RAW_RTP.
                        // So all the supported formats should work with RTP.
                        // We'll just pick the first one.

                        if (supported.length > 0) {
                              if (supported[0] instanceof VideoFormat) {
                                    // For video formats, we should double check the
                                    // sizes since not all formats work in all sizes.
                                    chosen = checkForVideoSizes(tracks[i].getFormat(),
                                                supported[0]);

                              } else
                                    chosen = supported[0];
                              tracks[i].setFormat(chosen);
                              System.err
                                          .println("Track " + i + " is set to transmit as:");
                              System.err.println("  " + chosen);
                              atLeastOneTrack = true;
                        } else
                              tracks[i].setEnabled(false);
                  } else
                        tracks[i].setEnabled(false);
            }

            if (!atLeastOneTrack)
                  return "Couldn't set any of the tracks to a valid RTP format";

            // Realize the processor. This will internally create a flow
            // graph and attempt to create an output datasource for JPEG/RTP
            // audio 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;
      }

      /**
       * @param ds
       */
      private void createPlayer(DataSource ds) {

            try {

                  Player player;

                  player = Manager.createRealizedPlayer(ds);

                  Component video = player.getVisualComponent();
                  
                  JFrame mediaFrame = new JFrame("Camera Screen");
                  mediaFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                  mediaFrame.add(video);

                  mediaFrame.setSize(300, 300);
                  mediaFrame.setVisible(true);
                  
                  player.getControlPanelComponent().setBounds(0, 90, 1208, 768);
                  
            
                  player.start();
                  
                  

            } catch (NoPlayerException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
            } catch (CannotRealizeException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
            } catch (NotRealizedError e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
            } catch (IOException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
            } catch (Exception e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
            }

      }

      /**
       * Use the RTPManager API to create sessions for each media
       * track of the processor.
       */
      private String createTransmitter() {

            PushBufferDataSource pbds = (PushBufferDataSource) dataOutput;
            PushBufferStream pbss[] = pbds.getStreams();

            rtpMgrs = new RTPManager[pbss.length];
            SessionAddress localAddr, destAddr;
            InetAddress ipAddr;
            SendStream sendStream;
            int port;
            SourceDescription srcDesList[];

            for (int i = 0; i < pbss.length; i++) {
                  try {
                        rtpMgrs[i] = RTPManager.newInstance();

                        port = portBase + 2 * i;
                        ipAddr = InetAddress.getByName(ipAddress);

                        localAddr = new SessionAddress(InetAddress.getLocalHost(), port);

                        destAddr = new SessionAddress(ipAddr, port);

                        rtpMgrs[i].initialize(localAddr);

                        rtpMgrs[i].addTarget(destAddr);

                        System.err.println("Created RTP session: " + ipAddress + " "
                                    + port);

                        sendStream = rtpMgrs[i].createSendStream(dataOutput, i);

                        sendStream.start();
                        
                  } catch (Exception e) {
                        return e.getMessage();
                  }
            }

            return null;
      }

      /**
       * For JPEG and H263, we know that they only work for particular
       * sizes.  So we'll perform extra checking here to make sure they
       * are of the right sizes.
       */
      Format checkForVideoSizes(Format original, Format supported) {

            int width, height;
            Dimension size = ((VideoFormat) original).getSize();
            Format jpegFmt = new Format(VideoFormat.JPEG_RTP);
            Format h263Fmt = new Format(VideoFormat.H263_RTP);

            if (supported.matches(jpegFmt)) {
                  // For JPEG, make sure width and height are divisible by 8.
                  width = (size.width % 8 == 0 ? size.width
                              : (int) (size.width / 8) * 8);
                  height = (size.height % 8 == 0 ? size.height
                              : (int) (size.height / 8) * 8);
            } else if (supported.matches(h263Fmt)) {
                  // For H.263, we only support some specific sizes.
                  if (size.width < 128) {
                        width = 128;
                        height = 96;
                  } else if (size.width < 176) {
                        width = 176;
                        height = 144;
                  } else {
                        width = 352;
                        height = 288;
                  }
            } else {
                  // We don't know this particular format.  We'll just
                  // leave it alone then.
                  return supported;
            }

            return (new VideoFormat(null, new Dimension(width, height),
                        Format.NOT_SPECIFIED, null, Format.NOT_SPECIFIED))
                        .intersects(supported);
      }

      /**
       * 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;
                  }
            }
      }

      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.
            while (p.getState() < state && !failed) {
                  synchronized (getStateLock()) {
                        try {
                              getStateLock().wait();
                        } catch (InterruptedException ie) {
                              return false;
                        }
                  }
            }

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

      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();
                        }
                  }
            }
      }

      public static void main(String[] args) {

            Format fmt = null;
            int i = 0;

      
            // Create a audio transmit object with the specified params.
            ServerTransmision serTransmision = new ServerTransmision();
            // Start the transmission
            String result = serTransmision.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
            // "Stop" button that would call stop to not transmit media anymore
            try {
                  Thread.currentThread().sleep(60000);
            } catch (InterruptedException ie) {
            }

            // Stops the transmission
            serTransmision.stop();

            System.err.println("...transmission ended.");

            System.exit(0);
      }

}
ASKER CERTIFIED SOLUTION
Avatar of qasitouch
qasitouch
Flag of Pakistan image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial