diff --git a/bigbluebutton-client/resources/prod/bbb-deskshare-applet-0.64.jar b/bigbluebutton-client/resources/prod/bbb-deskshare-applet-0.64.jar
index 29e3f2c6aa53b37b895c141406271f626aec0e53..514d1748de987b6c0dcc9af43613ffebb922e761 100755
Binary files a/bigbluebutton-client/resources/prod/bbb-deskshare-applet-0.64.jar and b/bigbluebutton-client/resources/prod/bbb-deskshare-applet-0.64.jar differ
diff --git a/deskshare/app/src/main/java/org/bigbluebutton/deskshare/server/socket/BlockStreamProtocolDecoder.java b/deskshare/app/src/main/java/org/bigbluebutton/deskshare/server/socket/BlockStreamProtocolDecoder.java
index 8a28d2ddbdef8af12b9ae4d0734f14185502af10..9550692673f1ec981e30763a90dba9b532f6dc6c 100755
--- a/deskshare/app/src/main/java/org/bigbluebutton/deskshare/server/socket/BlockStreamProtocolDecoder.java
+++ b/deskshare/app/src/main/java/org/bigbluebutton/deskshare/server/socket/BlockStreamProtocolDecoder.java
@@ -156,12 +156,21 @@ public class BlockStreamProtocolDecoder extends CumulativeProtocolDecoder {
     private void decodeCaptureUpdateEvent(IoSession session, IoBuffer in, ProtocolDecoderOutput out) {
     	String room = decodeRoom(session, in);
     	int seqNum = in.getInt();
-    	int position = in.getShort();
-    	boolean isKeyFrame = (in.get() == 1) ? true : false;
-    	int length = in.getInt();
-    	byte[] data = new byte[length];
-    	in.get(data, 0, length);    	
-    	CaptureUpdateBlockEvent event = new CaptureUpdateBlockEvent(room, position, data, isKeyFrame, seqNum);
-    	out.write(event);
+    	int numBlocks = in.getShort();
+//    	System.out.println("Number of blocks changed " + numBlocks);
+    	String blocksStr = "Blocks changed ";
+    	
+    	for (int i = 0; i < numBlocks; i++) {
+        	int position = in.getShort();
+        	blocksStr += " " + position;
+        	
+        	boolean isKeyFrame = (in.get() == 1) ? true : false;
+        	int length = in.getInt();
+        	byte[] data = new byte[length];
+        	in.get(data, 0, length);    	
+        	CaptureUpdateBlockEvent event = new CaptureUpdateBlockEvent(room, position, data, isKeyFrame, seqNum);
+        	out.write(event);    		
+    	}
+//    	System.out.println(blocksStr);
     }
 }
diff --git a/deskshare/applet/src/main/java/org/bigbluebutton/deskshare/client/blocks/BlockManager.java b/deskshare/applet/src/main/java/org/bigbluebutton/deskshare/client/blocks/BlockManager.java
index 9d8b8ba462e7c6b6de135ae04c5cddf78e83f347..466266dede28066e4d328868b12ad9dfb096bc6a 100755
--- a/deskshare/applet/src/main/java/org/bigbluebutton/deskshare/client/blocks/BlockManager.java
+++ b/deskshare/applet/src/main/java/org/bigbluebutton/deskshare/client/blocks/BlockManager.java
@@ -22,6 +22,7 @@ package org.bigbluebutton.deskshare.client.blocks;
 import java.awt.image.BufferedImage;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Vector;
 
 import org.bigbluebutton.deskshare.client.net.BlockMessage;
 import org.bigbluebutton.deskshare.common.Dimension;
@@ -57,14 +58,29 @@ public class BlockManager {
     
     public void processCapturedScreen(BufferedImage capturedScreen) {    	
     	long start = System.currentTimeMillis();
+
+		Vector<Integer> changedBlocks = new Vector<Integer>();
+/*		
+		for (int row = 1; row <= numRows; row++) {
+			for (int col = 1; col <= numColumns; col++) {
+	        	Block block = blocksMap.get(new Integer(row * col));
+	        	if (block.hasChanged(capturedScreen)) {
+	        		changedBlocks.add(new Integer(row * col));        		
+	        	}				
+			}
+			if (changedBlocks.size() > 0)
+				notifyChangedBlockListener(new BlockMessage(changedBlocks));
+		}  
+*/
 		int numberOfBlocks = numColumns * numRows;
-        for (int position = 1; position <= numberOfBlocks; position++) {
-        	Block block = blocksMap.get(new Integer(position));
+		for (int position = 1; position <= numberOfBlocks; position++) {
+			Block block = blocksMap.get(new Integer(position));
         	if (block.hasChanged(capturedScreen)) {
-        		notifyChangedBlockListener(new BlockMessage(block.getPosition()));
+        		changedBlocks.add(new Integer(position));        		
         	}
-        }
-        
+		}
+		if (changedBlocks.size() > 0)
+			notifyChangedBlockListener(new BlockMessage(changedBlocks));
 		long end = System.currentTimeMillis();
 //		System.out.println("ProcessCapturedScreen took " + (end-start) + " ms.");
     }
diff --git a/deskshare/applet/src/main/java/org/bigbluebutton/deskshare/client/net/BlockMessage.java b/deskshare/applet/src/main/java/org/bigbluebutton/deskshare/client/net/BlockMessage.java
index 33a073a26f03fe40b8cbbf4b34bdbc1878ff8629..65651adfd9a4502ea0a15c55c269858ae0128ad7 100755
--- a/deskshare/applet/src/main/java/org/bigbluebutton/deskshare/client/net/BlockMessage.java
+++ b/deskshare/applet/src/main/java/org/bigbluebutton/deskshare/client/net/BlockMessage.java
@@ -19,12 +19,14 @@
  */
 package org.bigbluebutton.deskshare.client.net;
 
+import java.util.Vector;
+
 public class BlockMessage implements Message {
 
-	private int position;
+	private Vector<Integer> blocks;
 	
-	public BlockMessage(int position) {
-		this.position = position;
+	public BlockMessage(Vector<Integer> blocks) {
+		this.blocks = blocks;
 	}
 	
 	@Override
@@ -32,7 +34,7 @@ public class BlockMessage implements Message {
 		return MessageType.BLOCK;
 	}
 
-	public int getPosition() {
-		return position;
+	public Vector<Integer> getBlocks() {
+		return blocks;
 	}
 }
diff --git a/deskshare/applet/src/main/java/org/bigbluebutton/deskshare/client/net/BlockStreamProtocolEncoder.java b/deskshare/applet/src/main/java/org/bigbluebutton/deskshare/client/net/BlockStreamProtocolEncoder.java
index aaca5753badcfd7699eec03422a02900f1468c2e..a035e3e96e1882f1f0afa2489b68e02e35788cfb 100755
--- a/deskshare/applet/src/main/java/org/bigbluebutton/deskshare/client/net/BlockStreamProtocolEncoder.java
+++ b/deskshare/applet/src/main/java/org/bigbluebutton/deskshare/client/net/BlockStreamProtocolEncoder.java
@@ -64,7 +64,34 @@ public class BlockStreamProtocolEncoder {
 		data.write(intToBytes(length));			
 		data.write(block.getVideoData());		
 	}
-		
+
+	public static void numBlocksChanged(int numBlocks, ByteArrayOutputStream data) throws IOException{
+		byte[] nb = new byte[2];
+		nb[0] = (byte)((numBlocks >> 8) & 0xff);
+		nb[1] = (byte)(numBlocks & 0xff);
+		data.write(nb);
+	}
+	
+	public static void encodeRoomAndSequenceNumber(String room, int seqNum, ByteArrayOutputStream data) throws IOException{
+		data.write(CAPTURE_UPDATE_EVENT);
+		encodeRoom(data, room);		
+		encodeSequenceNumber(data, seqNum);		
+	}
+	
+	public static void encodeBlock(BlockVideoData block, ByteArrayOutputStream data) throws IOException {				
+		byte[] position = new byte[2];
+		int pos = block.getPosition();
+		position[0] = (byte)((pos >> 8) & 0xff);
+		position[1] = (byte)(pos & 0xff);
+			
+		data.write(position);
+		data.write(block.isKeyFrame() ? 1:0);
+			
+		int length = block.getVideoData().length;			
+		data.write(intToBytes(length));			
+		data.write(block.getVideoData());		
+	}
+	
 	public static byte[] encodeHeaderAndLength(ByteArrayOutputStream data) throws IOException {
 		ByteArrayOutputStream header = new ByteArrayOutputStream();
 		header.write(HEADER);
diff --git a/deskshare/applet/src/main/java/org/bigbluebutton/deskshare/client/net/NetworkHttpStreamSender.java b/deskshare/applet/src/main/java/org/bigbluebutton/deskshare/client/net/NetworkHttpStreamSender.java
index 0f2c31c90a9e6b2909b1d7ff70931ba2caf8b984..f43f03b84692de2a961ec408e3a5a5b24e58e18f 100755
--- a/deskshare/applet/src/main/java/org/bigbluebutton/deskshare/client/net/NetworkHttpStreamSender.java
+++ b/deskshare/applet/src/main/java/org/bigbluebutton/deskshare/client/net/NetworkHttpStreamSender.java
@@ -166,10 +166,10 @@ public class NetworkHttpStreamSender implements Runnable {
 	
 	private void processNextMessageToSend(Message message) {
 		if (message.getMessageType() == Message.MessageType.BLOCK) {
-			EncodedBlockData block = retriever.getBlockToSend(((BlockMessage)message).getPosition());
-			BlockVideoData	bv = new BlockVideoData(room, block.getPosition(), block.getVideoData(), false /* should remove later */);									
-			sendBlockData(bv);
-			retriever.blockSent(block.getPosition());
+//			EncodedBlockData block = retriever.getBlockToSend(((BlockMessage)message).getPosition());
+//			BlockVideoData	bv = new BlockVideoData(room, block.getPosition(), block.getVideoData(), false /* should remove later */);									
+//			sendBlockData(bv);
+//			retriever.blockSent(block.getPosition());
 		} else if (message.getMessageType() == Message.MessageType.CURSOR) {
 			CursorMessage msg = (CursorMessage)message;
 			sendCursor(msg.getMouseLocation(), msg.getRoom());
diff --git a/deskshare/applet/src/main/java/org/bigbluebutton/deskshare/client/net/NetworkSocketStreamSender.java b/deskshare/applet/src/main/java/org/bigbluebutton/deskshare/client/net/NetworkSocketStreamSender.java
index 1ef8482bf275bda20c7e983a207b16ca6f6ff937..5a61c39417c19ba1caa8271d9ed8e060a6b8a0d4 100755
--- a/deskshare/applet/src/main/java/org/bigbluebutton/deskshare/client/net/NetworkSocketStreamSender.java
+++ b/deskshare/applet/src/main/java/org/bigbluebutton/deskshare/client/net/NetworkSocketStreamSender.java
@@ -25,6 +25,7 @@ import java.io.DataOutputStream;
 import java.io.IOException;
 import java.net.Socket;
 import java.net.UnknownHostException;
+import java.util.Vector;
 
 import org.bigbluebutton.deskshare.client.ExitCode;
 import org.bigbluebutton.deskshare.common.Dimension;
@@ -131,10 +132,29 @@ public class NetworkSocketStreamSender implements Runnable {
 	
 	private void processNextMessageToSend(Message message) throws IOException {
 		if (message.getMessageType() == Message.MessageType.BLOCK) {
-			EncodedBlockData block = retriever.getBlockToSend(((BlockMessage)message).getPosition());
-			BlockVideoData	bv = new BlockVideoData(room, block.getPosition(), block.getVideoData(), false /* should remove later */);									
-			sendBlock(bv);
-			retriever.blockSent(block.getPosition());
+			ByteArrayOutputStream dataToSend = new ByteArrayOutputStream();
+			dataToSend.reset();
+			BlockStreamProtocolEncoder.encodeRoomAndSequenceNumber(room, seqNumGenerator.getNext(), dataToSend);
+			
+			Object[] changedBlocks = ((BlockMessage)message).getBlocks().toArray();
+
+			BlockStreamProtocolEncoder.numBlocksChanged(changedBlocks.length, dataToSend);
+//			System.out.println("Number of blocks changed: " + changedBlocks.length);
+			String blocksStr = "Encoding ";
+			for (int i = 0; i < changedBlocks.length; i++) {
+				blocksStr += " " + (Integer)changedBlocks[i];
+				EncodedBlockData block = retriever.getBlockToSend((Integer)changedBlocks[i]);
+				BlockVideoData	bv = new BlockVideoData(room, block.getPosition(), block.getVideoData(), false /* should remove later */);	
+				BlockStreamProtocolEncoder.encodeBlock(bv, dataToSend);
+			}
+			
+//			System.out.println(blocksStr);
+			
+			sendHeader(BlockStreamProtocolEncoder.encodeHeaderAndLength(dataToSend));
+			sendToStream(dataToSend);
+			for (int i = 0; i< changedBlocks.length; i++) {
+				retriever.blockSent((Integer)changedBlocks[i]);
+			}
 		} else if (message.getMessageType() == Message.MessageType.CURSOR) {
 			CursorMessage msg = (CursorMessage)message;
 			sendCursor(msg.getMouseLocation(), msg.getRoom());