More on desktop streaming.

cusax-fix
Sebastien Vincent 16 years ago
parent d6df3d9a01
commit 67e5dc87ca

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

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

@ -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 :

@ -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 <tt>java.awt.Robot</tt>
* 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;
}
}

Loading…
Cancel
Save