FileDocCategorySizeDatePackage
Handler.javaAPI DocJMF 2.1.1e20373Mon May 12 12:20:58 BST 2003com.sun.media.content.rtp

Handler

public class Handler extends BasicPlayer implements BufferListener, ReceiveStreamListener
MediaPlayer extends BasicPlayer and uses MediaEngine to play media.

Fields Summary
RTPSessionMgr[]
mgrs
DataSource[]
sources
Player[]
players
Format[]
formats
Format[]
formatChanged
boolean[]
realized
boolean[]
dataReady
Vector
locators
ControllerListener
listener
boolean
playersRealized
Object
realizedSync
Object
closeSync
Object
dataSync
Object
stateLock
private boolean
closed
private boolean
audioEnabled
private boolean
videoEnabled
private boolean
prebuffer
private boolean
dataAllReady
private static JMFSecurity
jmfSecurity
private static boolean
securityPrivelege
private Method[]
m
private Class[]
cl
private Object[]
args
String
sessionError
Constructors Summary
public Handler()

    

      
        framePositioning = false;
	bufferControl = new BC();
	stopThreadEnabled = true;
    
Methods Summary
public synchronized voidaddController(javax.media.Controller newController)

	int playerState = getState();
	
	if (playerState == Started) {
	    throwError(new ClockStartedError("Cannot add controller to a started player"));
	}
	
	if ( (playerState == Unrealized) || (playerState == Realizing) ) {
	    throwError(new NotRealizedError("A Controller cannot be added to an Unrealized Player"));
	}

	throw new IncompatibleTimeBaseException();
    
protected booleanaudioEnabled()

	return audioEnabled;
    
protected voidcompleteRealize()

	state = Realized;
	super.completeRealize();
    
protected voiddoClose()


	closed = true;

	synchronized (realizedSync) {
	    realizedSync.notify();
	}

	synchronized (dataSync) {
	    dataSync.notifyAll();
	}

	stop();
	for (int i = 0; i < players.length; i++) {
	    try {
		if (players[i] != null)
		    players[i].close();
	    } catch (Exception e) {}
	}

	// close the RTP session.
	synchronized (closeSync) {
	    for (int i = 0; i < mgrs.length; i++) {
		if (mgrs[i] != null) {
                    mgrs[i].removeTargets( "Closing session from the RTP Handler");
                    mgrs[i].dispose();
		    mgrs[i] = null;
		}
	    }
	}

	super.doClose();
    
protected voiddoDeallocate()

	for (int i = 0; i < players.length; i++) {
	    try {
		if (players[i] != null)
		    players[i].deallocate();
	    } catch (Exception e) {}
	}
	synchronized (realizedSync) {
	    realizedSync.notify();
	}
    
protected voiddoFailedRealize()


	synchronized (closeSync) {

	    for (int i = 0; i < mgrs.length; i++) {
		if (mgrs[i] != null) {
		    mgrs[i].removeTargets( "Closing session from the RTP Handler");
		    mgrs[i].dispose();
		    mgrs[i] = null;
		}
	    }
	}

	super.doFailedRealize();
    
protected booleandoRealize()

    
       

        super.doRealize();

        try {
            
            if (source instanceof RTPSocket) {
                // this constructor will take care of initliasing and
                // starting the session as well as updating the encodings
                // from the RTPControl
		
		mgrs = new RTPSessionMgr[1];

                mgrs[1] = new RTPSessionMgr((RTPSocket)source);
		mgrs[1].addReceiveStreamListener(this);

		sources = new DataSource[1];
		players = new Player[1];
		formats = new Format[1];
		realized = new boolean[1];
		dataReady = new boolean[1];
		formatChanged = new Format[1];

		sources[0] = source;
		dataReady[0] = false;

            } else {
		RTPMediaLocator rml;
		InetAddress ipAddr;
		SessionAddress localAddr = new SessionAddress();
		SessionAddress destAddr;

		mgrs = new RTPSessionMgr[locators.size()];
		sources = new DataSource[locators.size()];
		players = new Player[locators.size()];
		formats = new Format[locators.size()];
		realized = new boolean[locators.size()];
		dataReady = new boolean[locators.size()];
		formatChanged = new Format[locators.size()];

		for (int i = 0; i < locators.size(); i++) {
		    rml = (RTPMediaLocator)locators.elementAt(i);
		    realized[i] = false;

		    mgrs[i] = (RTPSessionMgr) RTPManager.newInstance();
		    mgrs[i].addReceiveStreamListener(this);

		    ipAddr = InetAddress.getByName(rml.getSessionAddress());

		    if( ipAddr.isMulticastAddress()) {
			// local and remote address pairs are identical:
			localAddr= new SessionAddress( ipAddr,
						   rml.getSessionPort(),
						   rml.getTTL());

			destAddr = new SessionAddress( ipAddr,
						   rml.getSessionPort(),
						   rml.getTTL());
			    
		    } else {
			localAddr= new SessionAddress(InetAddress.getLocalHost(),
			  		           rml.getSessionPort());

                        destAddr = new SessionAddress(ipAddr,
						   rml.getSessionPort());
		    }
			
		    mgrs[ i].initialize( localAddr);
		    
		    if (prebuffer) {
			BufferControl bc = (BufferControl)mgrs[i].getControl("javax.media.control.BufferControl");
			bc.setBufferLength(bufferControl.getBufferLength());
			bc.setMinimumThreshold(bufferControl.getMinimumThreshold());
		    }
		    
    		    mgrs[i].addTarget(destAddr);
		}
	    }
            
        } catch (Exception e){
            Log.error("Cannot create the RTP Session: " + e.getMessage());
	    processError = sessionError;
            return false;
        }

	// dont realize this meta player until our player is realized
	try{
	    synchronized (realizedSync) {
		while (!playersRealized && !isInterrupted() && !closed)
		    realizedSync.wait();
	    }
	} catch (Exception e) {}

	// If realize is being interrupted, return failure from realize.
	if (closed || isInterrupted()) {
	    resetInterrupt();
	    processError = "no RTP data was received."; 
	    return false;
	}

        return true;
    
protected voiddoStart()

	super.doStart();

	synchronized (dataSync) {
	    if (prebuffer) {
		dataAllReady = false;
		for (int i = 0; i < dataReady.length; i++) {
		    dataReady[i] = false;
		    ((com.sun.media.protocol.rtp.DataSource)sources[i]).flush();
		    ((com.sun.media.protocol.rtp.DataSource)sources[i]).prebuffer();
		}
		// Wait atmost 3 secs for data prebuffering.
		if (!dataAllReady && !closed) {
		    try {
			dataSync.wait(3000);
		    } catch (Exception e) {}
		}
		//System.err.println("data prebuffered: " + dataAllReady);
	    }
	}

	// Start the component players.
	for (int i = 0; i < players.length; i++) {
	    try {
		if (players[i] != null)
		    waitForStart(players[i]);
		    //players[i].start();
	    } catch (Exception e) {}
	}
    
protected voiddoStop()

	super.doStop();

	synchronized (dataSync) {
	    if (prebuffer) {
		dataSync.notify();
	    }
	}

	// Stop the component players.
	for (int i = 0; i < players.length; i++) {
	    try {
		if (players[i] != null)
		    waitForStop(players[i]);
		    //players[i].stop();
	    } catch (Exception e) {}
	}
    
public javax.media.Control[]getControls()
Return the list of controls from its slave controllers plus the ones that this player supports.

return
the list of controls supported by this player.

	if (controls != null)
	    return controls;

	// build the list of controls.  It is the total of all the
	// controls from each controllers plus the ones that are maintained
	// by the player itself (e.g. playbackControl).

	Vector cv = new Vector();

	if (cachingControl != null)
	    cv.addElement(cachingControl);

	if (bufferControl != null)
	    cv.addElement(bufferControl);

	Control c;
	Object cs[];
	Controller ctrller;
	int i, size = players.length;
	for (i = 0; i < size; i++) {
	    ctrller = (Controller)players[i];
	    cs = ctrller.getControls();
	    if (cs == null) continue;
	    for (int j = 0; j < cs.length; j++) {
		cv.addElement(cs[j]);
	    }
	}

	Control ctrls[];
	size = cv.size();
	ctrls = new Control[size];

	for (i = 0; i < size; i++) {
	    ctrls[i] = (Control)cv.elementAt(i);
	}

	// If the player has already been realized, we'll save what
	// we've collected this time.  Then next time, we won't need
	// to go through this expensive search again. 
	if (getState() >= Realized)
	    controls = ctrls;

	return ctrls;
    
protected javax.media.TimeBasegetMasterTimeBase()

	return new SystemTimeBase();
    
public java.awt.ComponentgetVisualComponent()
Obtain the visiual component from the media engine.

        /**
         * Call the superclass method to ensure that restrictions
         * on player methods are enforced
         */
        super.getVisualComponent();
	for (int i = 0; i < players.length; i++) {
	    if (players[i] != null && players[i].getVisualComponent() != null)
		return players[i].getVisualComponent();
	}
        return null;
    
private voidinvalidateComp()

	controlComp = null;
	controls = null;
    
public voidminThresholdReached(javax.media.protocol.DataSource ds)

	boolean ready = true;
	synchronized (dataSync) {
	    for (int i = 0; i < sources.length; i++) {
		if (sources[i] == ds)
		    dataReady[i] = true;
		else if (!dataReady[i])
		    ready = false;
	    }
	    if (!ready)
		return;

	    dataAllReady = true;
	    dataSync.notify();
	}
    
private voidsendMyEvent(javax.media.ControllerEvent e)

	super.sendEvent(e);
    
public floatsetRate(float rate)

	if (getState() < Realized) {
	    throwError(new NotRealizedError("Cannot set rate on an unrealized Player."));
	}

	// Cannot play any rate other than 1.0.
	return 1.0f;
    
public voidsetSource(javax.media.protocol.DataSource source)

            super.setSource(source);
            if (source instanceof com.sun.media.protocol.rtp.DataSource){
                MediaLocator ml = source.getLocator();
		String mlStr = ml.getRemainder();
		String str;
		int start, idx;

		start = 0;
		while (mlStr.charAt(start) == '/")
		    start++;
	 	locators = new Vector();
		RTPMediaLocator rml;
		try {
		    while (start < mlStr.length() &&
		 	    (idx = mlStr.indexOf("&", start)) != -1) {
			str = mlStr.substring(start, idx);
                	rml = new RTPMediaLocator("rtp://" + str);
			locators.addElement(rml);
			start = idx+1;
		    }
		    if (start != 0)
			str = mlStr.substring(start);
		    else
			str = mlStr;
                    rml = new RTPMediaLocator("rtp://" + str);
		    locators.addElement(rml);

                } catch (Exception e) {
		    throw new IncompatibleSourceException();
		}

		if (locators.size() > 1)
		    prebuffer = true;

            } else if (!(source instanceof RTPSocket)) {
                throw new IncompatibleSourceException();
	    }
		
            // we will set the dynamic encoding for the one
            // encoding we dont use from static RTP payloads
            RTPControl ctl = (RTPControl)
                        source.getControl("javax.media.rtp.RTPControl");
                if (ctl != null)
                    ctl.addFormat(new AudioFormat(AudioFormat.DVI_RTP,
                                     	          44100,
                                                  4,
                                                  1),
                                      18);
    
public voidsetStopTime(javax.media.Time t)

	controllerSetStopTime(t);
    
public voidsetTimeBase(javax.media.TimeBase tb)

    
protected voidstopAtTime()

	controllerStopAtTime();
    
public voidupdate(javax.media.rtp.event.ReceiveStreamEvent event)


	RTPSessionMgr mgr = (RTPSessionMgr)event.getSource();
	int idx;

	for (idx = 0; idx < mgrs.length; idx++) {
	    if (mgrs[idx] == mgr)
		break;
	}

	if (idx >= mgrs.length) {
	    // Something's wrong.
	    System.err.println("Unknown manager: " + mgr);
	    return;
	}

	if( event instanceof RemotePayloadChangeEvent) {
     
	    Log.comment("Received an RTP PayloadChangeEvent");
	    RTPControl ctl = (RTPControl)sources[idx].getControl("javax.media.rtp.RTPControl");

	    if (ctl != null)
		formatChanged[idx] = ctl.getFormat();

	    // payload has changed. we need to close the old player and
	    // create a new player  
	    if (players[idx] != null) {

		// stop player
		stop();

		// Now, close the rtp player.
		// Wait till the old player is closed
		waitForClose(players[idx]);
	    }

	    try {
		// when the player was closed, its datasource was
		// disconnected. Now we must reconnect the datasource before
		// a player can be created for it.
		sources[idx].connect();
		players[idx] = javax.media.Manager.createPlayer(sources[idx]);
        
		if (players[idx] == null) {
		    Log.error("Could not create player for the new RTP payload.");
		    return;
		}
		players[idx].addControllerListener(listener);
		players[idx].realize();

	    }catch (Exception e){
		Log.error("Could not create player for the new payload.");
	    }

	} // payload change event
    
	if (event instanceof NewReceiveStreamEvent){

	    if (players[idx] != null) {
		// We've already created a player for this.  So this must
		// be the second stream in the same session.  We won't
		// deal with it.
		return;
	    }

	    ReceiveStream stream = null;
	    try {
		stream =((NewReceiveStreamEvent)event).getReceiveStream();
		sources[idx] = stream.getDataSource();

		RTPControl ctl = (RTPControl)sources[idx].getControl("javax.media.rtp.RTPControl");
		if (ctl != null){
		    formats[idx] = ctl.getFormat();
		    if (formats[idx] instanceof AudioFormat)
			audioEnabled = true;
		    else if (formats[idx] instanceof VideoFormat)
			videoEnabled = true;
		}

		if (source instanceof RTPSocket)
		    ((RTPSocket)source).setChild(sources[idx]);
		else
		    ((com.sun.media.protocol.rtp.DataSource)source).
		      setChild((com.sun.media.protocol.rtp.DataSource)sources[idx]);
		// create a player by passing datasource to the Media Manager
		players[idx] = javax.media.Manager.createPlayer(sources[idx]);
		if (players[idx] == null)
		    return;

		players[idx].addControllerListener(listener);
		players[idx].realize();

		if (prebuffer)
		    ((com.sun.media.protocol.rtp.DataSource)sources[idx]).setBufferListener(this);

	    } catch (Exception e) {
		Log.error("NewReceiveStreamEvent exception " + e.getMessage());
		return;
	    }
        
	}// instanceof newReceiveStreamEvent
    
public voidupdateStats()

	for (int i = 0; i < players.length; i++) {
	    if (players[i] != null)
		((BasicPlayer)players[i]).updateStats();
	}
    
protected booleanvideoEnabled()

	return videoEnabled;
    
private voidwaitForClose(javax.media.Player p)

	(new StateWaiter()).waitForClose(p);
    
private voidwaitForStart(javax.media.Player p)

	(new StateWaiter()).waitForStart(p, true);
    
private voidwaitForStop(javax.media.Player p)

	(new StateWaiter()).waitForStart(p, false);