[Phission-cvs] phission/examples/java/JMFRTPPhissionFLIR/src AVReceiveJMF.java,NONE,1.1 AVTransmitJM
Brought to you by:
pthoren
Update of /cvsroot/phission/phission/examples/java/JMFRTPPhissionFLIR/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27366/src Added Files: AVReceiveJMF.java AVTransmitJMF.java Removed Files: AVReceive2.java AVTransmit2.java DataSource.java LiveStream.java Log Message: Added the ability to use both the raw phission jmf-rtp stream and the FLIROverlay in the same project. --- NEW FILE: AVTransmitJMF.java --- /* * @(#)AVTransmitJMF.java 1.4 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.*; import java.io.*; import java.net.InetAddress; import javax.media.*; import javax.media.protocol.*; import javax.media.protocol.DataSource; import javax.media.format.*; import javax.media.control.TrackControl; import javax.media.control.QualityControl; import javax.media.rtp.*; import javax.media.rtp.rtcp.*; import com.sun.media.rtp.*; /* ------------------------------------------------------------------------ */ public class AVTransmitJMF { // Input MediaLocator // Can be a file or http or capture source private MediaLocator locator; private String ipAddress; private int portBase; // When running both AVReceive and AVTransmit on the same machine, // can't have dest and local ports the same */ private int glbl_dest_port_offset = 0; private Processor processor = null; private RTPManager rtpMgrs[]; private DataSource dataOutput = null; /* -------------------------------------------------------------------- */ public AVTransmitJMF(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; // 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; 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 = javax.media.Manager.createDataSource(locator); } catch (Exception e) { return "Couldn't create DataSource"; } // Try to create a processor to handle the input media locator try { processor = javax.media.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[1] 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[1]); } else chosen = supported[1]; 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; } /* -------------------------------------------------------------------- */ // Use the RTPManager API to create sessions for each media // track of the processor. private String createTransmitter() { // Cheated. Should have checked the type. PushBufferDataSource pbds = (PushBufferDataSource)dataOutput; PushBufferStream pbss[]= pbds.getStreams(); rtpMgrs = new RTPManager[pbss.length]; SessionAddress localAddr; SessionAddress destAddr; InetAddress ipAddr; SendStream sendStream; int port; SourceDescription srcDesList[]; for (int i = 0; i < pbss.length; i++) { try { rtpMgrs[i] = RTPManager.newInstance(); // The local session address will be created on the // same port as the the target port. This is necessary // if you use AVTransmitJMF in conjunction with JMStudio. // JMStudio assumes - in a unicast session - that the // transmitter transmits from the same port it is receiving // on and sends RTCP Receiver Reports back to this port of // the transmitting host. port = portBase + 2*i; ipAddr = InetAddress.getByName(ipAddress); localAddr = new SessionAddress( InetAddress.getLocalHost(), port); destAddr = new SessionAddress( ipAddr, port + glbl_dest_port_offset); rtpMgrs[i].initialize( localAddr); rtpMgrs[i].addTarget( destAddr); System.err.println( "Created RTP session: " + ipAddress + " " + port); System.err.println( "----------------------(localAddr)-------------------------" ); System.err.println( localAddr ); System.err.println( "----------------------(destAddr)--------------------------" ); System.err.println( destAddr ); System.err.println( "----------------------------------------------------------" ); 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 = 0; int height = 0; Dimension size = ((VideoFormat)original).getSize(); Format jpegFmt = new Format(VideoFormat.JPEG_RTP); Format h263Fmt = new Format(VideoFormat.H263_RTP); System.err.println("Video Source Size: " + size); 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; } } } /* -------------------------------------------------------------------- */ // 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 AVTransmitJMF class public static void main(String [] args) { boolean foo_true = true; int total_sources = 0; AVTransmitJMF at[] = null; int i = 0; Format fmt = null; String result = null; // We need three parameters to do the transmission // For example, // java AVTransmitJMF file:/C:/media/test.mov 129.130.131.132 42050 if (args.length < 3) { prUsage(); } at = new AVTransmitJMF[args.length / 3]; for (i = 0; (i+2) < args.length; i += 3) { // Create a audio transmit object with the specified params. at[total_sources++] = new AVTransmitJMF(new MediaLocator(args[i]), args[i+1], args[i+2], fmt); } for (i = 0; i < at.length; i++ ) { // Start the transmission result = at[i].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 AVTransmitJMF while (foo_true) { try { Thread.currentThread().sleep(60000); } catch (InterruptedException ie) { } } for (i = 0; i < total_sources; i++ ) { // Stop the transmission at[i].stop(); } System.err.println("...transmission ended."); System.exit(0); } /* -------------------------------------------------------------------- */ static void prUsage() { System.err.println("Usage: AVTransmitJMF <sourceURL> <destIP> <destPortBase>"); System.err.println(" <sourceURL>: input URL or file name"); System.err.println(" <destIP>: multicast, broadcast or unicast IP address for the transmission"); System.err.println(" <destPortBase>: network port numbers for the transmission."); System.err.println(" The first track will use the destPortBase."); System.err.println(" The next track will use destPortBase + 2 and so on.\n"); System.exit(0); } } --- LiveStream.java DELETED --- --- DataSource.java DELETED --- --- NEW FILE: AVReceiveJMF.java --- /* * @(#)AVReceiveJMF.java 1.3 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.io.*; import java.awt.*; import java.net.*; import java.awt.event.*; import java.util.Vector; import javax.media.*; import javax.media.rtp.*; import javax.media.rtp.event.*; import javax.media.rtp.rtcp.*; import javax.media.protocol.*; import javax.media.protocol.DataSource; import javax.media.format.AudioFormat; import javax.media.format.VideoFormat; import javax.media.Format; import javax.media.format.FormatChangeEvent; import javax.media.control.BufferControl; /* ------------------------------------------------------------------------ */ // AVReceiveJMF to receive RTP transmission using the new RTP API. public class AVReceiveJMF implements ReceiveStreamListener, SessionListener, ControllerListener { /* When running both AVReceive and AVTransmit on the same machine, * can't have dest and local ports the same */ private int glbl_recv_port_offset = 0; String sessions[] = null; RTPManager mgrs[] = null; Vector playerWindows = null; boolean dataReceived = false; Object dataSync = new Object(); /* -------------------------------------------------------------------- */ public AVReceiveJMF(String sessions[]) { this.sessions = sessions; } /* -------------------------------------------------------------------- */ protected boolean initialize() { try { InetAddress ipAddr; SessionAddress localAddr = new SessionAddress(); SessionAddress destAddr; mgrs = new RTPManager[sessions.length]; playerWindows = new Vector(); SessionLabel session; // Open the RTP sessions. for (int i = 0; i < sessions.length; i++) { // Parse the session addresses. try { session = new SessionLabel(sessions[i]); } catch (IllegalArgumentException e) { System.err.println("Failed to parse the session address given: " + sessions[i]); return false; } System.err.println(" - Open RTP session for: addr: " + session.addr + " port: " + session.port + " ttl: " + session.ttl); mgrs[i] = (RTPManager) RTPManager.newInstance(); mgrs[i].addSessionListener(this); mgrs[i].addReceiveStreamListener(this); ipAddr = InetAddress.getByName(session.addr); if( ipAddr.isMulticastAddress()) { // local and remote address pairs are identical: localAddr= new SessionAddress( ipAddr, session.port, session.ttl); destAddr = new SessionAddress( ipAddr, session.port, session.ttl); } else { localAddr= new SessionAddress( InetAddress.getLocalHost(), session.port + glbl_recv_port_offset); destAddr = new SessionAddress( ipAddr, session.port); } System.err.println( "----------------------(localAddr)-------------------------" ); System.err.println( localAddr ); System.err.println( "----------------------(destAddr)--------------------------" ); System.err.println( destAddr ); System.err.println( "----------------------------------------------------------" ); mgrs[i].initialize( localAddr); // You can try out some other buffer size to see // if you can get better smoothness. BufferControl bc = (BufferControl)mgrs[i].getControl("javax.media.control.BufferControl"); if (bc != null) bc.setBufferLength(350); mgrs[i].addTarget(destAddr); } } catch (Exception e) { System.err.println("Cannot create the RTP Session: " + e.getMessage()); return false; } // Wait for data to arrive before moving on. long then = System.currentTimeMillis(); long waitingPeriod = 30000; // wait for a maximum of 30 secs. try { synchronized (dataSync) { while (!dataReceived && System.currentTimeMillis() - then < waitingPeriod) { if (!dataReceived) System.err.println(" - Waiting for RTP data to arrive..."); dataSync.wait(1000); } } } catch (Exception e) { } if (!dataReceived) { System.err.println("No RTP data was received."); close(); return false; } return true; } /* -------------------------------------------------------------------- */ public boolean isDone() { return playerWindows.size() == 0; } /* -------------------------------------------------------------------- */ // Close the players and the session managers. protected void close() { for (int i = 0; i < playerWindows.size(); i++) { try { ((PlayerWindow)playerWindows.elementAt(i)).close(); } catch (Exception e) { } } playerWindows.removeAllElements(); // close the RTP session. for (int i = 0; i < mgrs.length; i++) { if (mgrs[i] != null) { mgrs[i].removeTargets( "Closing session from AVReceiveJMF"); mgrs[i].dispose(); mgrs[i] = null; } } } /* -------------------------------------------------------------------- */ PlayerWindow find(Player p) { for (int i = 0; i < playerWindows.size(); i++) { PlayerWindow pw = (PlayerWindow)playerWindows.elementAt(i); if (pw.player == p) return pw; } return null; } /* -------------------------------------------------------------------- */ PlayerWindow find(ReceiveStream strm) { for (int i = 0; i < playerWindows.size(); i++) { PlayerWindow pw = (PlayerWindow)playerWindows.elementAt(i); if (pw.stream == strm) return pw; } return null; } /* -------------------------------------------------------------------- */ // SessionListener. public synchronized void update(SessionEvent evt) { if (evt instanceof NewParticipantEvent) { Participant p = ((NewParticipantEvent)evt).getParticipant(); System.err.println(" - A new participant had just joined: " + p.getCNAME()); } } /* -------------------------------------------------------------------- */ // ReceiveStreamListener public synchronized void update( ReceiveStreamEvent evt) { RTPManager mgr = (RTPManager)evt.getSource(); Participant participant = evt.getParticipant(); // could be null. ReceiveStream stream = evt.getReceiveStream();// could be null. if (evt instanceof RemotePayloadChangeEvent) { System.err.println(" - Received an RTP PayloadChangeEvent."); System.err.println("Sorry, cannot handle payload change."); System.exit(0); } else if (evt instanceof NewReceiveStreamEvent) { try { stream = ((NewReceiveStreamEvent)evt).getReceiveStream(); DataSource ds = stream.getDataSource(); // Find out the formats. RTPControl ctl = (RTPControl)ds.getControl("javax.media.rtp.RTPControl"); if (ctl != null) { System.err.println(" - Recevied new RTP stream: " + ctl.getFormat()); } else System.err.println(" - Recevied new RTP stream"); if (participant == null) System.err.println(" The sender of this stream had yet to be identified."); else { System.err.println(" The stream comes from: " + participant.getCNAME()); } // create a player by passing datasource to the Media Manager Player p = javax.media.Manager.createPlayer(ds); if (p == null) return; p.addControllerListener(this); p.realize(); PlayerWindow pw = new PlayerWindow(p, stream); playerWindows.addElement(pw); // Notify intialize() that a new stream had arrived. synchronized (dataSync) { dataReceived = true; dataSync.notifyAll(); } } catch (Exception e) { System.err.println("NewReceiveStreamEvent exception " + e.getMessage()); return; } } else if (evt instanceof StreamMappedEvent) { if (stream != null && stream.getDataSource() != null) { DataSource ds = stream.getDataSource(); // Find out the formats. RTPControl ctl = (RTPControl)ds.getControl("javax.media.rtp.RTPControl"); System.err.println(" - The previously unidentified stream "); if (ctl != null) System.err.println(" " + ctl.getFormat()); System.err.println(" had now been identified as sent by: " + participant.getCNAME()); } } else if (evt instanceof ByeEvent) { System.err.println(" - Got \"bye\" from: " + participant.getCNAME()); PlayerWindow pw = find(stream); if (pw != null) { pw.close(); playerWindows.removeElement(pw); } } } /* -------------------------------------------------------------------- */ // ControllerListener for the Players. public synchronized void controllerUpdate(ControllerEvent ce) { Player p = (Player)ce.getSourceController(); if (p == null) return; // Get this when the internal players are realized. if (ce instanceof RealizeCompleteEvent) { PlayerWindow pw = find(p); if (pw == null) { // Some strange happened. System.err.println("Internal error!"); System.exit(-1); } pw.initialize(); pw.setVisible(true); p.start(); } if (ce instanceof ControllerErrorEvent) { p.removeControllerListener(this); PlayerWindow pw = find(p); if (pw != null) { pw.close(); playerWindows.removeElement(pw); } System.err.println("AVReceiveJMF internal error: " + ce); } } /* -------------------------------------------------------------------- */ // A utility class to parse the session addresses. class SessionLabel { public String addr = null; public int port; public int ttl = 1; SessionLabel(String session) throws IllegalArgumentException { int off; String portStr = null; String ttlStr = null; if (session != null && session.length() > 0) { while (session.length() > 1 && session.charAt(0) == '/') session = session.substring(1); // Now see if there's a addr specified. off = session.indexOf('/'); if (off == -1) { if (!session.equals("")) addr = session; } else { addr = session.substring(0, off); session = session.substring(off + 1); // Now see if there's a port specified off = session.indexOf('/'); if (off == -1) { if (!session.equals("")) portStr = session; } else { portStr = session.substring(0, off); session = session.substring(off + 1); // Now see if there's a ttl specified off = session.indexOf('/'); if (off == -1) { if (!session.equals("")) ttlStr = session; } else { ttlStr = session.substring(0, off); } } } } if (addr == null) throw new IllegalArgumentException(); if (portStr != null) { try { Integer integer = Integer.valueOf(portStr); if (integer != null) port = integer.intValue(); } catch (Throwable t) { throw new IllegalArgumentException(); } } else throw new IllegalArgumentException(); if (ttlStr != null) { try { Integer integer = Integer.valueOf(ttlStr); if (integer != null) ttl = integer.intValue(); } catch (Throwable t) { throw new IllegalArgumentException(); } } } } /* -------------------------------------------------------------------- */ // GUI classes for the Player. class PlayerWindow extends Frame { Player player; ReceiveStream stream; /* ---------------------------------------------------------------- */ PlayerWindow(Player p, ReceiveStream strm) { player = p; stream = strm; } /* ---------------------------------------------------------------- */ public void initialize() { add(new PlayerPanel(player)); } /* ---------------------------------------------------------------- */ public void close() { player.close(); setVisible(false); dispose(); } /* ---------------------------------------------------------------- */ public void addNotify() { super.addNotify(); pack(); } } /* -------------------------------------------------------------------- */ // GUI classes for the Player. class PlayerPanel extends Panel { Component vc, cc; PlayerPanel(Player p) { setLayout(new BorderLayout()); if ((vc = p.getVisualComponent()) != null) add("Center", vc); if ((cc = p.getControlPanelComponent()) != null) add("South", cc); } /* ---------------------------------------------------------------- */ public Dimension getPreferredSize() { int w = 0; int h = 0; if (vc != null) { Dimension size = vc.getPreferredSize(); w = size.width; h = size.height; } if (cc != null) { Dimension size = cc.getPreferredSize(); if (w == 0) w = size.width; h += size.height; } if (w < 160) w = 160; return new Dimension(w, h); } } /* -------------------------------------------------------------------- */ public static void main(String argv[]) { if (argv.length == 0) prUsage(); AVReceiveJMF avReceive = new AVReceiveJMF(argv); if (!avReceive.initialize()) { System.err.println("Failed to initialize the sessions."); System.exit(-1); } // Check to see if AVReceiveJMF is done. try { while (!avReceive.isDone()) Thread.sleep(1000); } catch (Exception e) { } System.err.println("Exiting AVReceiveJMF"); } /* -------------------------------------------------------------------- */ static void prUsage() { System.err.println("Usage: AVReceiveJMF <session> <session> ..."); System.err.println(" <session>: <address>/<port>/<ttl>"); System.exit(0); } }// end of AVReceiveJMF --- AVTransmit2.java DELETED --- --- AVReceive2.java DELETED --- |