diff --git a/src/net/java/sip/communicator/impl/neomedia/imgstreaming/ImageStreamingUtils.java b/src/net/java/sip/communicator/impl/neomedia/imgstreaming/ImageStreamingUtils.java index 8d9ec88e1..46b241f1f 100644 --- a/src/net/java/sip/communicator/impl/neomedia/imgstreaming/ImageStreamingUtils.java +++ b/src/net/java/sip/communicator/impl/neomedia/imgstreaming/ImageStreamingUtils.java @@ -44,6 +44,7 @@ public static BufferedImage getScaledImage(BufferedImage src, int width, int hei tx.scale(scaleWidth, scaleHeight); op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR); dst = new BufferedImage(width, height, type); + return op.filter(src, dst); } @@ -61,28 +62,11 @@ public static byte[] getImageByte(BufferedImage src) return null; } -if(false) -{ - /* get raw bytes */ - int intData[] = ((DataBufferInt)src.getData().getDataBuffer()).getData(); - byte data[] = new byte[intData.length * 4]; - - /* convert to byte (Java is always big endian) */ - for(int i = 0 ; i < intData.length ; i++) - { - data[(i * 4) + 3] = (byte)(intData[i] >>> 24); - data[(i * 4) + 2] = (byte)(intData[i] >>> 16); - data[(i * 4) + 1] = (byte)(intData[i] >>> 8); - data[(i * 4)] = (byte)(intData[i]); - } - return data; -} - WritableRaster raster = src.getRaster(); byte data[] = null; + int pixel[] = new int[4]; int width = src.getWidth(); int height = src.getHeight(); - int pixel[] = new int[4]; int off = 0; /* allocate our bytes array */ diff --git a/src/net/java/sip/communicator/impl/neomedia/imgstreaming/RobotDesktopInteractImpl.java b/src/net/java/sip/communicator/impl/neomedia/imgstreaming/RobotDesktopInteractImpl.java index d3f71cee5..f9513bbd5 100644 --- a/src/net/java/sip/communicator/impl/neomedia/imgstreaming/RobotDesktopInteractImpl.java +++ b/src/net/java/sip/communicator/impl/neomedia/imgstreaming/RobotDesktopInteractImpl.java @@ -29,7 +29,7 @@ public class RobotDesktopInteractImpl implements DesktopInteract /** * Screen capture robot. */ - private Robot robot = new Robot(); + private Robot robot = null; /** * The unique instance of this class (singleton). @@ -38,11 +38,8 @@ public class RobotDesktopInteractImpl implements DesktopInteract /** * Constructor. - * - * @throws AWTException if platform configuration does not allow low-level input control - * @throws SecurityException if Robot creation is not permitted */ - private RobotDesktopInteractImpl() throws AWTException, SecurityException + private RobotDesktopInteractImpl() { } @@ -58,7 +55,9 @@ public static RobotDesktopInteractImpl getInstance() throws AWTException, Securi if(instance == null) { instance = new RobotDesktopInteractImpl(); + instance.robot = new Robot(); } + return instance; } @@ -91,10 +90,10 @@ public BufferedImage captureScreen(int x, int y, int width, int height) return null; } - logger.info("Begin " + System.nanoTime()); + logger.info("Begin capture: " + System.nanoTime()); rect = new Rectangle(x, y, width, height); img = robot.createScreenCapture(rect); - logger.info("End " + System.nanoTime()); + logger.info("End capture: " + System.nanoTime()); return img; } diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/imgstreaming/DataSource.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/imgstreaming/DataSource.java index 63b24f320..0cb6d7d30 100644 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/imgstreaming/DataSource.java +++ b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/imgstreaming/DataSource.java @@ -138,7 +138,7 @@ public PushBufferStream[] getStreams() { stream = new ImageStream(getLocator()); /* XXX allow to select other format */ - stream.setFormat(getFormats()[4]); + stream.setFormat(getFormats()[5]); } return (stream == null) ? EMPTY_STREAMS : diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/imgstreaming/ImageStream.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/imgstreaming/ImageStream.java index 20c325f61..245bdc7d2 100644 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/imgstreaming/ImageStream.java +++ b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/imgstreaming/ImageStream.java @@ -15,13 +15,15 @@ import javax.media.format.*; import javax.media.protocol.*; +import net.sf.fmj.utility.*; + import net.java.sip.communicator.util.*; import net.java.sip.communicator.impl.neomedia.imgstreaming.*; /** * The stream used by JMF for our image streaming. * - * This class launch a thread to handle java.awt.Robot + * This class launch a thread to handle desktop capture * interactions. * * @author Sebastien Vincent @@ -72,9 +74,9 @@ public class ImageStream implements PushBufferStream, Runnable private boolean started = false; /** - * Last desktop screen. + * Buffer container. */ - private BufferedImage screen = null; + private RingBuffer ringBuffer = null; /** * Constructor. @@ -120,46 +122,23 @@ public Format getFormat() */ public void read(Buffer buffer) throws IOException { - /* TODO get last screen capture of the desktop, - * convert and put the result in buffer - */ - RGBFormat format = (RGBFormat)currentFormat; - int intData[] = null; - byte data[] = null; - /* BufferedImage screen = null; */ - BufferedImage scaledScreen = null; - int width = (int)format.getSize().getWidth(); - int height = (int)format.getSize().getHeight(); - - /* get last screencapture and resize it */ try { - scaledScreen = ImageStreamingUtils.getScaledImage( - screen, width, height, BufferedImage.TYPE_INT_ARGB); + /* get the next data */ + Buffer buf = (Buffer)ringBuffer.get(); + + buffer.setData(buf.getData()); + buffer.setOffset(0); + buffer.setLength(buf.getLength()); + buffer.setFormat(buf.getFormat()); + buffer.setHeader(null); + buffer.setTimeStamp(buf.getTimeStamp()); + buffer.setSequenceNumber(buf.getSequenceNumber()); + buffer.setFlags(buf.getFlags()); } catch(Exception e) { - logger.warn("Cannot capture screen."); - return; } - - long t = System.nanoTime(); - - data = ImageStreamingUtils.getImageByte(scaledScreen); - - t = System.nanoTime() - t; - /* System.out.println("Time: " + t); */ - - buffer.setData(data); - buffer.setOffset(0); - buffer.setLength(data.length * 4); - buffer.setFormat(currentFormat); - buffer.setHeader(null); - buffer.setTimeStamp(System.nanoTime()); - buffer.setSequenceNumber(seqNo); - seqNo++; - - buffer.setFlags(Buffer.FLAG_LIVE_DATA | Buffer.FLAG_SYSTEM_TIME); } /** @@ -270,9 +249,10 @@ public void start() { if(captureThread == null || !captureThread.isAlive()) { - System.out.println("Start stream!"); + logger.info("Start stream"); captureThread = new Thread(this); captureThread.start(); + ringBuffer = new RingBuffer(5); started = true; } } @@ -282,7 +262,7 @@ public void start() */ public void stop() { - System.out.println("Stop stream!"); + logger.info("Stop stream"); started = false; captureThread = null; } @@ -292,8 +272,29 @@ public void stop() */ public void run() { - screen = null; + final Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); + final RGBFormat format = (RGBFormat)currentFormat; + final int width = (int)format.getSize().getWidth(); + final int height = (int)format.getSize().getHeight(); + BufferedImage scaledScreen = null; + BufferedImage screen = null; + Buffer buffer = new Buffer(); + byte data[] = null; + /* capture first full desktop screen + try + { + screen = RobotDesktopInteractImpl.getInstance().captureScreen(); + scaledScreen = ImageStreamingUtils.getScaledImage(screen, + width, height, BufferedImage.TYPE_INT_ARGB); + } + catch(Exception e) + { + } + + screen = null; + */ +/* synchronized(this) { while(transferHandler == null && started) @@ -307,28 +308,63 @@ public void run() } } } - +*/ while(started) { - if(started && transferHandler != null) + try { - try - { - screen = RobotDesktopInteractImpl.getInstance().captureScreen(); - transferHandler.transferData(this); + long t = System.nanoTime(); - /* 200 ms */ - Thread.sleep(200); - } - catch(AWTException ae) - { - logger.warn("Desktop capture failed!"); - } - catch (InterruptedException e) + /* get desktop screen and resize it */ + screen = RobotDesktopInteractImpl.getInstance().captureScreen(); + scaledScreen = ImageStreamingUtils.getScaledImage(screen, + width, height, BufferedImage.TYPE_INT_ARGB); + + /* get raw bytes */ + data = ImageStreamingUtils.getImageByte(scaledScreen); + + /* add it to a RingBuffer and notify JMF that new data + * is available + */ + buffer.setData(data); + buffer.setOffset(0); + buffer.setLength(data.length); + buffer.setFormat(currentFormat); + buffer.setHeader(null); + buffer.setTimeStamp(System.nanoTime()); + buffer.setSequenceNumber(seqNo); + buffer.setFlags(Buffer.FLAG_LIVE_DATA | Buffer.FLAG_SYSTEM_TIME); + seqNo++; + + ringBuffer.put(buffer); + + /* pass to JMF handler */ + if(transferHandler != null) { + transferHandler.transferData(this); } + + t = System.nanoTime() - t; + logger.info("Desktop capture processing time: " + t); + + /* cleanup */ + screen = null; + scaledScreen = null; + data = null; + + /* 500 ms */ + Thread.sleep(500); + } + catch(AWTException ae) + { + logger.warn("Desktop capture failed!"); + } + catch (InterruptedException e) + { } } + + buffer = null; } }