You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openmeetings.apache.org by so...@apache.org on 2012/04/08 06:25:18 UTC

svn commit: r1310951 - in /incubator/openmeetings/trunk/singlewebapp: ./ src/ src/org/openmeetings/screen/webstart/

Author: solomax
Date: Sun Apr  8 04:25:18 2012
New Revision: 1310951

URL: http://svn.apache.org/viewvc?rev=1310951&view=rev
Log:
OPENMEETINGS-138 The issue is partially fixed (not completely tested)

Added:
    incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/screen/webstart/BaseScreenEncoder.java
Modified:
    incubator/openmeetings/trunk/singlewebapp/build.xml
    incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/screen/webstart/CoreScreenShare.java
    incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/screen/webstart/ScreenV1Encoder.java
    incubator/openmeetings/trunk/singlewebapp/src/screenshare.vm

Modified: incubator/openmeetings/trunk/singlewebapp/build.xml
URL: http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/build.xml?rev=1310951&r1=1310950&r2=1310951&view=diff
==============================================================================
--- incubator/openmeetings/trunk/singlewebapp/build.xml (original)
+++ incubator/openmeetings/trunk/singlewebapp/build.xml Sun Apr  8 04:25:18 2012
@@ -327,6 +327,8 @@
 			<fileset dir="${red5.server.lib}" includes="bcprov-jdk16*.jar" />
 			<fileset dir="${red5.server.lib}" includes="ehcache-core*.jar" />
 			<fileset dir="${red5.server.lib}" includes="commons-beanutils*.jar" />
+			<fileset dir="${red5.server.lib}" includes="jcl-over-slf4j*.jar" />
+			<fileset dir="${red5.server.lib}" includes="commons-collections*.jar" />
 			<fileset dir="${red5.lib}" includes="red5.jar" />
 			<fileset dir="${red5.server.lib}" includes="spring-context-3*.jar" />
 			<fileset dir="${red5.server.lib}" includes="spring-core-*.jar" />

Added: incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/screen/webstart/BaseScreenEncoder.java
URL: http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/screen/webstart/BaseScreenEncoder.java?rev=1310951&view=auto
==============================================================================
--- incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/screen/webstart/BaseScreenEncoder.java (added)
+++ incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/screen/webstart/BaseScreenEncoder.java Sun Apr  8 04:25:18 2012
@@ -0,0 +1,25 @@
+package org.openmeetings.screen.webstart;
+
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.image.BufferedImage;
+
+public abstract class BaseScreenEncoder implements IScreenEncoder {
+
+	public BufferedImage resize(BufferedImage _img, Rectangle size) {
+		BufferedImage img = _img;
+		if (_img.getWidth() != size.width || _img.getHeight() != size.height) {
+			img = new BufferedImage(size.width, size.height,
+					BufferedImage.TYPE_INT_RGB);
+
+			Graphics2D graphics2D = img.createGraphics();
+			graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
+					RenderingHints.VALUE_INTERPOLATION_BICUBIC);
+			graphics2D.drawImage(_img, 0, 0, size.width, size.height, null);
+			graphics2D.dispose();
+		}
+		return img;
+	}
+	
+}

Modified: incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/screen/webstart/CoreScreenShare.java
URL: http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/screen/webstart/CoreScreenShare.java?rev=1310951&r1=1310950&r2=1310951&view=diff
==============================================================================
--- incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/screen/webstart/CoreScreenShare.java (original)
+++ incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/screen/webstart/CoreScreenShare.java Sun Apr  8 04:25:18 2012
@@ -66,10 +66,6 @@ public class CoreScreenShare {
 	public String publishName;
 	public ITagWriter writer;
 	public ITagReader reader;
-	public int videoTs = 0;
-	public int audioTs = 0;
-	public int kt = 0;
-	public int kt2 = 0;
 	public IoBuffer buffer;
 	public CaptureScreen capture = null;
 	public Thread thread = null;
@@ -532,52 +528,32 @@ public class CoreScreenShare {
 		logger.debug("ScreenShare startStream");
 		this.publishName = publishName;
 
-		videoTs = 0;
-		audioTs = 0;
-		kt = 0;
-		kt2 = 0;
-
 		try {
-
 			if (!isConnected) {
 				instance.connect(host, port, app, instance);
 			} else {
 				setConnectionAsSharingClient();
 			}
-
 		} catch (Exception e) {
 			logger.error("ScreenShare startStream exception " + e);
 		}
-
 	}
 
 	protected void onInvoke(RTMPConnection conn, Channel channel,
 			Header source, Notify invoke, RTMP rtmp) {
 
 		if (invoke.getType() == IEvent.Type.STREAM_DATA) {
-			// logger.debug("Ignoring stream data notify with header: {}",
-			// source);
 			return;
 		}
-		// logger.debug("onInvoke: {}, invokeId: {}", invoke, invoke
-		// .getInvokeId());
-
-		// logger.debug("ServiceMethodName :: "+
-		// invoke.getCall().getServiceMethodName());
-		// logger.debug("Arguments :: "+ invoke.getCall().getArguments());
 
 		if (invoke.getCall().getServiceMethodName()
 				.equals("sendRemoteCursorEvent")) {
-
 			sendRemoteCursorEvent(invoke.getCall().getArguments()[0]);
-
 		}
-
 	}
 
 	public void stopStream() {
 		try {
-
 			logger.debug("ScreenShare stopStream");
 
 			isConnected = false;
@@ -586,7 +562,6 @@ public class CoreScreenShare {
 			capture.stop();
 			capture.release();
 			thread = null;
-
 		} catch (Exception e) {
 			logger.error("ScreenShare stopStream exception " + e);
 		}
@@ -1105,7 +1080,7 @@ public class CoreScreenShare {
 			return;
 
 		if (buffer == null) {
-			buffer = IoBuffer.allocate(1024);
+			buffer = IoBuffer.allocate(video.length);
 			buffer.setAutoExpand(true);
 		}
 
@@ -1116,8 +1091,6 @@ public class CoreScreenShare {
 		VideoData videoData = new VideoData(buffer);
 		videoData.setTimestamp((int) ts);
 
-		kt++;
-
 		RTMPMessage rtmpMsg = RTMPMessage.build(videoData);
 		instance.publishStreamData(publishStreamId, rtmpMsg);
 	}
@@ -1131,8 +1104,6 @@ public class CoreScreenShare {
 	private final class CaptureScreen extends Object implements Runnable {
 		private int timeBetweenFrames = 1000; // frameRate
 
-		private volatile long timestamp = 0;
-
 		private volatile boolean active = true;
 		@SuppressWarnings("unused")
 		private volatile boolean stopped = false;
@@ -1178,28 +1149,24 @@ public class CoreScreenShare {
 		public void run() {
 			try {
 				Robot robot = new Robot();
-
+				BufferedImage image = null;
 				while (active) {
-					final long ctime = System.currentTimeMillis();
-
 					Rectangle screen = new Rectangle(VirtualScreenBean.vScreenSpinnerX,
 							VirtualScreenBean.vScreenSpinnerY,
 							VirtualScreenBean.vScreenSpinnerWidth,
 							VirtualScreenBean.vScreenSpinnerHeight);
 					
-					BufferedImage image = robot.createScreenCapture(screen);
+					final long ctime = System.currentTimeMillis();
+					image = robot.createScreenCapture(screen);
 
 					try {
-						timestamp += timeBetweenFrames;
-
 						byte[] data = se.encode(screen, image, new Rectangle(VirtualScreenBean.vScreenResizeX,
 								VirtualScreenBean.vScreenResizeY));
 
-						pushVideo(data.length, data, timestamp);
+						pushVideo(data.length, data, ctime);
 					} catch (Exception e) {
 						e.printStackTrace();
 					}
-
 					final int spent = (int) (System.currentTimeMillis() - ctime);
 
 					sendCursorStatus();

Modified: incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/screen/webstart/ScreenV1Encoder.java
URL: http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/screen/webstart/ScreenV1Encoder.java?rev=1310951&r1=1310950&r2=1310951&view=diff
==============================================================================
--- incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/screen/webstart/ScreenV1Encoder.java (original)
+++ incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/screen/webstart/ScreenV1Encoder.java Sun Apr  8 04:25:18 2012
@@ -18,23 +18,27 @@
  */
 package org.openmeetings.screen.webstart;
 
-import java.awt.Graphics2D;
 import java.awt.Rectangle;
-import java.awt.RenderingHints;
 import java.awt.image.BufferedImage;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
-import java.util.zip.DeflaterOutputStream;
+import java.util.zip.Deflater;
 
-public class ScreenV1Encoder implements IScreenEncoder {
+public class ScreenV1Encoder extends BaseScreenEncoder {
 	private BufferedImage last = null;
 	private static int KEY_FRAME_INDEX = 100;
 	private static int DEFAULT_BLOCK_SIZE = 32;
+	private static int DEFAULT_SCREEN_WIDTH = 1920;
+	private static int DEFAULT_SCREEN_HEIGHT = 1080;
 	private int keyFrameIndex;
 	private int frameCount = 0;
 	private int blockSize;
 	private Rectangle screen;
+	private ByteArrayOutputStream ba = new ByteArrayOutputStream(50 + 3 * DEFAULT_SCREEN_WIDTH * DEFAULT_SCREEN_HEIGHT);
+	private byte[] areaBuf = null;
+	private Deflater d = new Deflater(Deflater.DEFAULT_COMPRESSION);
+	private byte[] zipBuf = null;
 	
 	public ScreenV1Encoder() {
 		this(KEY_FRAME_INDEX, DEFAULT_BLOCK_SIZE);
@@ -47,30 +51,18 @@ public class ScreenV1Encoder implements 
 			throw new RuntimeException("Invalid block size passed: " + blockSize + " should be: 'from 16 to 256 in multiples of 16'");
 		}
 		this.blockSize = blockSize;
-	}
-	
-	public BufferedImage resize(BufferedImage _img, Rectangle size) {
-		BufferedImage img = _img;
-		if (_img.getWidth() != size.width || _img.getHeight() != size.height) {
-			img = new BufferedImage(size.width, size.height,
-					BufferedImage.TYPE_INT_RGB);
 
-			Graphics2D graphics2D = img.createGraphics();
-			graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
-					RenderingHints.VALUE_INTERPOLATION_BICUBIC);
-			graphics2D.drawImage(_img, 0, 0, size.width, size.height, null);
-			graphics2D.dispose();
-		}
-		return img;
+		areaBuf = new byte[3 * blockSize * blockSize];
+		zipBuf = new byte[3 * blockSize * blockSize];
 	}
 	
 	public byte[] encode(Rectangle screen, BufferedImage _img, Rectangle size) throws IOException {
 		BufferedImage img = resize(_img, size);
+		ba.reset();
 		Rectangle imgArea = new Rectangle(img.getWidth(), img.getHeight());
 		Rectangle area = getNextBlock(imgArea, null);
-		boolean isKeyFrame = (frameCount++ % keyFrameIndex) == 0 || last == null || (screen.equals(this.screen));
+		boolean isKeyFrame = (frameCount++ % keyFrameIndex) == 0 || last == null || !screen.equals(this.screen);
 		
-		ByteArrayOutputStream ba = new ByteArrayOutputStream(50 + 3 * imgArea.width * imgArea.height);
 		//header
 		ba.write(getTag(isKeyFrame ? 0x01 : 0x02, 0x03));
 		writeShort(ba, imgArea.width + ((blockSize / 16 - 1) << 12));
@@ -110,26 +102,25 @@ public class ScreenV1Encoder implements 
 
 	private void writeBytesIfChanged(ByteArrayOutputStream ba, boolean isKeyFrame, BufferedImage img, Rectangle area) throws IOException {
 		boolean changed = isKeyFrame;
-		ByteArrayOutputStream baos = new ByteArrayOutputStream(3 * area.width * area.height);
-		DeflaterOutputStream dos = new DeflaterOutputStream(baos);
+		int count = 0;
 		for (int y = area.y + area.height - 1; y >= area.y; --y) {
 			for (int x = area.x; x < area.x + area.width; ++x) {
 				int pixel = img.getRGB(x, y);
 				if (!changed && pixel != last.getRGB(x, y)) {
 					changed = true;
 				}
-				dos.write(new byte[]{
-					(byte)(pixel & 0xFF)				// Blue component
-					, (byte)((pixel >> 8) & 0xFF)		// Green component
-					, (byte)((pixel >> 16) & 0xFF)		// Red component
-				});
+				areaBuf[count++] = (byte)(pixel & 0xFF);			// Blue component
+				areaBuf[count++] = (byte)((pixel >> 8) & 0xFF);		// Green component
+				areaBuf[count++] = (byte)((pixel >> 16) & 0xFF);	// Red component
 			}
 		}
-		dos.finish();
 		if (changed) {
-			final int written = baos.size();
+			d.reset();
+			d.setInput(areaBuf, 0, count);
+			d.finish();
+			int written = d.deflate(zipBuf);
 			writeShort(ba, written);
-			ba.write(baos.toByteArray(), 0, written);
+			ba.write(zipBuf, 0, written);
 		} else {
 			writeShort(ba, 0);
 		}

Modified: incubator/openmeetings/trunk/singlewebapp/src/screenshare.vm
URL: http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/screenshare.vm?rev=1310951&r1=1310950&r2=1310951&view=diff
==============================================================================
--- incubator/openmeetings/trunk/singlewebapp/src/screenshare.vm (original)
+++ incubator/openmeetings/trunk/singlewebapp/src/screenshare.vm Sun Apr  8 04:25:18 2012
@@ -32,6 +32,8 @@ limitations under the License.
         <jar href="bcprov-jdk16-145.jar"/> 
         <jar href="commons-beanutils-1.8.3.jar"/> 
         <jar href="commons-codec-1.6.jar"/>
+        <jar href="commons-collections-3.2.1.jar"/>
+        <jar href="jcl-over-slf4j-1.6.1.jar"/>
         <jar href="com.springsource.slf4j.api-1.6.1.jar"/>
         <jar href="ehcache-core-2.5.0.jar"/>
         <jar href="httpclient-4.1.2.jar" />