FileDocCategorySizeDatePackage
MonitorAdapter.javaAPI DocJMF 2.1.1e12798Mon May 12 12:20:56 BST 2003com.sun.media.controls

MonitorAdapter

public class MonitorAdapter extends Object implements MonitorControl, Owned

Fields Summary
protected CodecChain
cc
protected boolean
enabled
protected boolean
closed
protected Component
visualComponent
protected Component
controlComponent
protected Checkbox
cbEnabled
protected Format
format
protected float
inFrameRate
protected float
previewFrameRate
protected long
lastPreviewTime
protected long
previewInterval
protected MouseListener
ml
protected PopupMenu
rateMenu
protected LoopThread
loopThread
protected int[]
frameRates
CircularBuffer
bufferQ
Object
owner
private static JMFSecurity
jmfSecurity
private static boolean
securityPrivelege
private Method[]
mSecurity
private Class[]
clSecurity
private Object[]
argsSecurity
static VideoFormat
mpegVideo
Constructors Summary
public MonitorAdapter(Format f, Object owner)


     
	try {
	    jmfSecurity = JMFSecurityManager.getJMFSecurity();
	    securityPrivelege = true;
	} catch (SecurityException e) {
	}
    
	format = f;
	this.owner = owner;
    
Methods Summary
private voidaddPopupMenu(java.awt.Component visual)

	MenuItem mi;
	ActionListener rateSelect;
	visualComponent = visual;
	rateMenu = new PopupMenu("Monitor Rate");

	rateSelect = new ActionListener() {
	    public void actionPerformed(ActionEvent ae) {
		String action = ae.getActionCommand();
		int space = action.indexOf(" ");
		String rateString = action.substring(0, space);
		try {
		    int rate = Integer.parseInt(rateString);
		    setPreviewFrameRate((float)rate);
		} catch (Throwable t) {
		    if (t instanceof ThreadDeath)
		        throw (ThreadDeath) t;
		}
	    }
	};
	
	visual.add(rateMenu);
	int lastAdded = 0;

	for (int i = 0; i < frameRates.length; i++) {
	    if (frameRates[i] < inFrameRate) {
		mi = new MenuItem(frameRates[i] + " fps");
		rateMenu.add(mi);
		mi.addActionListener(rateSelect);
		lastAdded = frameRates[i];
	    }
	}

	if (lastAdded < inFrameRate) {
	    mi = new MenuItem(inFrameRate + " fps");
	    rateMenu.add(mi);
	    mi.addActionListener(rateSelect);
	}
	
	visual.addMouseListener( ml = new MouseAdapter() {
	    public void mousePressed(MouseEvent me) {
		if (me.isPopupTrigger())
		    rateMenu.show(visualComponent, me.getX(), me.getY());
	    }

	    public void mouseReleased(MouseEvent me) {
		if (me.isPopupTrigger())
		    rateMenu.show(visualComponent, me.getX(), me.getY());
	    }

	    public void mouseClicked(MouseEvent me) {
		if (me.isPopupTrigger())
		    rateMenu.show(visualComponent, me.getX(), me.getY());
	    }
	} );
    
public voidclose()


	if (cc == null)
	    return;

	loopThread.kill();
	synchronized (bufferQ) {
	    closed = true;
	    bufferQ.notifyAll();
	}

	cc.close();
	cc = null;
    
private java.lang.ObjectcopyData(java.lang.Object in)

	if (in instanceof byte[]) {
	    byte [] out = new byte[((byte[])in).length];
	    System.arraycopy(in, 0, out, 0, out.length);
	    return out;
	}
	if (in instanceof short[]) {
	    short [] out = new short[((short[])in).length];
	    System.arraycopy(in, 0, out, 0, out.length);
	    return out;
	}
	if (in instanceof int[]) {
	    int [] out = new int[((int[])in).length];
	    System.arraycopy(in, 0, out, 0, out.length);
	    return out;
	}
	return in;
    
public booleandoProcess()

	Buffer buffer;

	// Grab a filled buffer from the queue.
	synchronized (bufferQ) {
	    while (!bufferQ.canRead() && enabled && !closed) {
		try {
		    bufferQ.wait();
		} catch (Exception e) {}
	    }

	    if (closed)
		return false;
	    else if (!enabled)
		return true;

	    buffer = bufferQ.read();
	}

	boolean toDisplay = false;

	if (buffer.getFormat() instanceof AudioFormat) {
	    toDisplay = true;
	} else {
	    long time = buffer.getTimeStamp();
	    if (time >= lastPreviewTime + previewInterval || 
		time <= lastPreviewTime) {
		if (mpegVideo.matches(format)) {
		    /*
		     * Only set toDisplay true on MPEG I frames.
		     * This way VideoCodecChain can treat the stream
		     * as a raw format and avoid overloading the
		     * CPU by sending every frame to the decoder.
		     * Downside is it limits the framerate that can
		     * be set for the monitor.
		     */
		    byte[] payload = (byte[])buffer.getData();
		    int offset = buffer.getOffset();
		    int ptype = payload[offset+2] & 0x07;
		    if (ptype == 1) {
			lastPreviewTime = time;
			toDisplay = true;
		    }
		} else {
		    lastPreviewTime = time;
		    toDisplay = true;
		}
	    } else
		toDisplay = false;
	}

	// Use the codec chain to process the data.
	cc.process(buffer, toDisplay);

	// Return the processed buffer back to the queue.
	synchronized (bufferQ) {
	    bufferQ.readReport();
	    bufferQ.notifyAll();
	}

	return true;
    
public voidfinalize()

	if (visualComponent != null) {
	    visualComponent.remove(rateMenu);
	    visualComponent.removeMouseListener(ml);
	}
    
public java.awt.ComponentgetControlComponent()

	/*
	if (controlComponent == null) {
	    if (cc != null)
		visualComponent = getVisualComponent();
	    if (visualComponent == null)
		return null;
	    southPanel = new Panel();
	    listBox = new List(6);
	    for (int i = 0; i <= inFrameRate; i++) {
		listBox.add(i + " fps");
	    }
	    southPanel.add(new Label("Monitor Frame Rate : "));
	    southPanel.add(listBox);
			   
	    preferredSize = visualComponent.getPreferredSize();
	    preferredSize.height += southPanel.getPreferredSize().height;
	    
	    controlComponent = new Panel(new BorderLayout()) {
		public Dimension getPreferredSize() {
		    return preferredSize;
		}
	    };

	    controlComponent.add("Center", visualComponent);
	    controlComponent.add("South", southPanel);

	}
	*/

	if (controlComponent != null)
	    return controlComponent;

	if (cc == null && !open())
	    return null;

	controlComponent = cc.getControlComponent();

	// Create Audio Monitor Panel
	if (format instanceof AudioFormat && controlComponent != null) {
	    Container controlPanel = new Panel();
	    controlPanel.setLayout( new BorderLayout() );
	    cbEnabled = new Checkbox("Monitor Audio");
	    controlPanel.add("West", cbEnabled);
	    controlPanel.add("Center", controlComponent);
	    controlComponent = controlPanel;
            controlPanel.setBackground ( java.awt.Color.lightGray );
	}

	if (format instanceof VideoFormat && controlComponent != null) {
	    Container controlPanel = new Panel();
	    controlPanel.setLayout( new BorderLayout() );
	    cbEnabled = new Checkbox("Monitor Video");
	    controlPanel.add("South", cbEnabled);
	    controlPanel.add("Center", controlComponent);
	    addPopupMenu(controlComponent);
	    controlComponent = controlPanel;
            controlPanel.setBackground ( java.awt.Color.lightGray );
	}

	if (cbEnabled != null) {
	    cbEnabled.setState(isEnabled());
	    cbEnabled.addItemListener( new ItemListener() {
		public void itemStateChanged(ItemEvent ie) {
		    MonitorAdapter.this.setEnabled(cbEnabled.getState());
		}
	    } );
	}
	//

	return controlComponent;
    
public java.lang.ObjectgetOwner()

	return owner;
    
public booleanisEnabled()

	return enabled;
    
protected booleanopen()

	try {

	    if (format instanceof VideoFormat) {
		VideoFormat vf = (VideoFormat)format;
		cc = new VideoCodecChain(vf);
		inFrameRate = vf.getFrameRate();
		if (inFrameRate < 0) // if unspecified
		    inFrameRate = 30f;
		inFrameRate = ((int)(inFrameRate * 10 + 0.5)) / 10f;
	    } else if (format instanceof AudioFormat) {
		cc = new AudioCodecChain((AudioFormat)format);
	    }

	} catch (UnsupportedFormatException e) {
	    Log.warning("Failed to initialize the monitor control: " + e);
	    return false;
	}

	if (cc == null)
	    return false;

	bufferQ = new CircularBuffer(2);
	if ( jmfSecurity != null ) {
	    String permission = null;
	    try {
		if (jmfSecurity.getName().startsWith("jmf-security")) {
		    permission = "thread";
		    jmfSecurity.requestPermission(mSecurity, clSecurity, argsSecurity,
						  JMFSecurity.THREAD);
		    mSecurity[0].invoke(clSecurity[0], argsSecurity[0]);
		    
		    permission = "thread group";
		    jmfSecurity.requestPermission(mSecurity, clSecurity, argsSecurity,
						  JMFSecurity.THREAD_GROUP);
		    mSecurity[0].invoke(clSecurity[0], argsSecurity[0]);
		} else if (jmfSecurity.getName().startsWith("internet")) {
		    PolicyEngine.checkPermission(PermissionID.THREAD);
		    PolicyEngine.assertPermission(PermissionID.THREAD);
		}
	    } catch (Throwable e) {
		if (JMFSecurityManager.DEBUG) {
		    System.err.println( "Unable to get " + permission +
					" privilege  " + e);
		}
		securityPrivelege = false;
		// TODO: Do the right thing if permissions cannot be obtained.
		// User should be notified via an event
	    }
	}
	if ( (jmfSecurity != null) && (jmfSecurity.getName().startsWith("jdk12"))) {
	    try {
  		Constructor cons = CreateWorkThreadAction.cons;
 		loopThread = (MonitorThread) jdk12.doPrivM.invoke(
					  jdk12.ac,
 					  new Object[] {
					      cons.newInstance(
						  new Object[] {
						      MonitorThread.class,
						      MonitorAdapter.class,
						      this
                                           })});
	    } catch (Exception e) {
	    }
	} else {
	    loopThread = new MonitorThread(this);
	}

	return true;
    
public voidprocess(javax.media.Buffer input)


	if (input == null || previewFrameRate <= 0 || 
	    format == null || input.isEOM() || input.isDiscard() ||
	    (input.getFlags() & input.FLAG_FLUSH) != 0) {
	    return;
	}

	if (!format.matches(input.getFormat())) {
	    return;
	}

	Buffer buffer = null;

	// Grab an empty buffer from the queue.
	synchronized (bufferQ) {
	    while (!bufferQ.canWrite() && enabled && !closed) {
		try {
		    bufferQ.wait();
		} catch (Exception e) {}
	    }

	    if (!enabled || closed)
		return;

	    buffer = bufferQ.getEmptyBuffer();
	}

	// expensive copy
	buffer.setData(copyData(input.getData()));
	buffer.setFlags(input.getFlags());
	buffer.setFormat(input.getFormat());
	buffer.setSequenceNumber(input.getSequenceNumber());
	buffer.setHeader(input.getHeader());
	buffer.setLength(input.getLength());
	buffer.setOffset(input.getOffset());
	buffer.setTimeStamp(input.getTimeStamp());

	// Put the buffer into the queue.
	synchronized (bufferQ) {
	    bufferQ.writeReport();
	    bufferQ.notifyAll();
	}
    
public voidreset()

	if (cc != null)
	    cc.reset();
    
public booleansetEnabled(boolean on)


	if (on) {
	    if (cc == null) {
		if (!open())
		    return false;
	    } else
		cc.reset();
	    if (!cc.prefetch())
		return false;


	    // Flush the bufferQ.
	    synchronized (bufferQ) {
		while (bufferQ.canRead()) {
		    bufferQ.read();
		    bufferQ.readReport();
		}
	    }

	    enabled = true;
	    loopThread.start();
	} else if (!on && cc != null) {
	    loopThread.pause();
	    // In case we are blocked at the process call.
	    synchronized (bufferQ) { 
		enabled = false;
		bufferQ.notifyAll();
	    }
	    cc.deallocate();
	}

	return enabled;
    
public floatsetPreviewFrameRate(float value)

	if (value > inFrameRate)
	    value = inFrameRate;
	previewFrameRate = value;
	previewInterval = (long) (1E+9 / value);
	return value;