You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@openmeetings.apache.org by "seba.wagner@gmail.com" <se...@gmail.com> on 2012/03/29 19:11:15 UTC

Re: svn commit: r1306748 - in /incubator/openmeetings/trunk/singlewebapp: ./ WebContent/red5-screenshare/ src/org/openmeetings/app/installation/ src/org/red5/screen/webstart/ src/org/red5/screen/webstart/gui/

Hi Maxim,

nice job :) Have you find something in the Specs for the protocol?

Btw: Sharing or recording with medium or low quality throws some exception
now:
java.lang.IllegalArgumentException: Width (0) and height (2048) cannot be
<= 0
    at
java.awt.image.DirectColorModel.createCompatibleWritableRaster(Unknown
Source)
    at java.awt.image.BufferedImage.<init>(Unknown Source)
    at
org.red5.screen.webstart.ScreenV1Encoder.resize(ScreenV1Encoder.java:55)
    at
org.red5.screen.webstart.ScreenV1Encoder.encode(ScreenV1Encoder.java:68)
    at
org.red5.screen.webstart.CommonScreenShare$CaptureScreen.run(CommonScreenShare.java:1195)
    at java.lang.Thread.run(Unknown Source)

About the quality settings in the client: Did you also change the "normal"
(high) quality that it does _not_ rescale the screen anymore? Previously
the factor was 1.3 for the normal modus. I don't think that this is
neccessary.

I think we should also fix the the package name to fit into our structure,
what do you think?

What did you mean by *The code still need to be reviewed to remove
copy/pasted code* ?

Thanks!
Sebastian


2012/3/29 <so...@apache.org>

> Author: solomax
> Date: Thu Mar 29 08:14:45 2012
> New Revision: 1306748
>
> URL: http://svn.apache.org/viewvc?rev=1306748&view=rev
> Log:
> Screen sharing client cleaned up from 'borrowed' code; code cleanup
>
> Added:
>
>  incubator/openmeetings/trunk/singlewebapp/WebContent/red5-screenshare/logback.xml
>
>  incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/IScreenEncoder.java
>
>  incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/ScreenV1Encoder.java
> Modified:
>    incubator/openmeetings/trunk/singlewebapp/build.xml
>
>  incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/installation/ImportInitvalues.java
>
>  incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/CommonScreenShare.java
>
>  incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreen.java
>
>  incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreenBean.java
>
> Added:
> incubator/openmeetings/trunk/singlewebapp/WebContent/red5-screenshare/logback.xml
> URL:
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/WebContent/red5-screenshare/logback.xml?rev=1306748&view=auto
>
> ==============================================================================
> ---
> incubator/openmeetings/trunk/singlewebapp/WebContent/red5-screenshare/logback.xml
> (added)
> +++
> incubator/openmeetings/trunk/singlewebapp/WebContent/red5-screenshare/logback.xml
> Thu Mar 29 08:14:45 2012
> @@ -0,0 +1,159 @@
> +<?xml version="1.0" encoding="UTF-8"?>
> +<configuration>
> +       <!-- Uncomment if you are using the logback plugin for eclipse
> +       <consolePlugin/>
> +       -->
> +       <appender name="CONSOLE"
> class="ch.qos.logback.core.ConsoleAppender">
> +               <encoder>
> +                       <pattern>[%p] [%thread] %logger - %msg%n</pattern>
> +               </encoder>
> +       </appender>
> +       <root>
> +               <level value="WARN" />
> +               <appender-ref ref="CONSOLE" />
> +       </root>
> +       <!-- Red5 -->
> +       <logger name="org.red5.server.Launcher">
> +               <level value="INFO" />
> +       </logger>
> +       <logger name="org.red5.io">
> +               <level value="INFO" />
> +       </logger>
> +    <logger name="org.red5.logging.DerbyLogInterceptor">
> +        <level value="WARN" />
> +    </logger>
> +    <logger name="org.red5.server">
> +        <level value="WARN" />
> +    </logger>
> +       <logger name="org.red5.server.Client">
> +               <level value="INFO" />
> +       </logger>
> +       <logger name="org.red5.server.api.stream.support">
> +               <level value="INFO" />
> +       </logger>
> +       <logger name="org.red5.server.cache">
> +               <level value="WARN" />
> +       </logger>
> +       <logger name="org.red5.server.jmx">
> +               <level value="WARN" />
> +       </logger>
> +       <logger name="org.red5.server.messaging.InMemoryPushPushPipe">
> +               <level value="INFO" />
> +       </logger>
> +       <logger name="org.red5.server.net">
> +               <level value="INFO" />
> +       </logger>
> +       <logger name="org.red5.server.net.rtmpt.RTMPTServlet">
> +               <level value="WARN" />
> +       </logger>
> +       <logger name="org.red5.server.net.servlet">
> +               <level value="WARN" />
> +       </logger>
> +       <logger name="org.red5.server.net.proxy">
> +               <level value="INFO" />
> +       </logger>
> +       <logger name="org.red5.server.net.remoting">
> +               <level value="WARN" />
> +       </logger>
> +       <logger name="org.red5.server.net.rtmp">
> +               <level value="WARN" />
> +       </logger>
> +       <logger name="org.red5.server.net.rtmp.BaseRTMPHandler">
> +               <level value="WARN" />
> +       </logger>
> +       <logger name="org.red5.server.net.rtmp.RTMPMinaIoHandler">
> +               <level value="WARN" />
> +       </logger>
> +       <logger name="org.red5.server.net.rtmp.status">
> +               <level value="INFO" />
> +       </logger>
> +       <logger name="org.red5.server.net.rtmpt">
> +               <level value="WARN" />
> +       </logger>
> +       <logger name="org.red5.server.persistence">
> +               <level value="WARN" />
> +       </logger>
> +       <logger name="org.red5.server.script">
> +               <level value="WARN" />
> +       </logger>
> +       <logger name="org.red5.server.service">
> +               <level value="INFO" />
> +       </logger>
> +       <logger name="org.red5.server.so">
> +               <level value="WARN" />
> +       </logger>
> +       <logger name="org.red5.server.stream">
> +               <level value="INFO" />
> +       </logger>
> +       <logger name="org.red5.server.stream.consumer">
> +               <level value="WARN" />
> +       </logger>
> +       <logger name="org.red5.server.net.mrtmp">
> +               <level value="WARN" />
> +       </logger>
> +       <!-- Mina -->
> +       <logger name="org.apache.mina">
> +               <level value="WARN" />
> +       </logger>
> +       <logger name="org.apache.mina.filter">
> +               <level value="WARN" />
> +       </logger>
> +       <logger
> name="org.red5.server.adapter.MultiThreadedApplicationAdapter" >
> +               <level value="INFO"/>
> +       </logger>
> +       <!-- Apache commons -->
> +       <logger name="org.apache.commons">
> +               <level value="WARN" />
> +       </logger>
> +       <logger name="httpclient">
> +               <level value="WARN" />
> +       </logger>
> +       <!-- Apache catalina / tomcat -->
> +    <logger name="org.red5.server.tomcat">
> +        <level value="INFO" />
> +    </logger>
> +    <logger name="org.apache.catalina">
> +        <level value="WARN" />
> +    </logger>
> +       <logger name="org.apache.jasper">
> +               <level value="INFO" />
> +       </logger>
> +       <logger name="org.apache.tomcat">
> +               <level value="INFO" />
> +       </logger>
> +       <logger name="org.apache.tomcat.util.net">
> +               <level value="WARN" />
> +       </logger>
> +       <logger name="org.apache.coyote.http11">
> +               <level value="INFO" />
> +       </logger>
> +       <!-- Spring -->
> +       <logger name="org.springframework">
> +               <level value="INFO" />
> +       </logger>
> +       <logger name="org.springframework.beans.factory">
> +               <level value="INFO" />
> +       </logger>
> +       <logger name="org.springframework.beans.factory.xml">
> +               <level value="WARN" />
> +       </logger>
> +       <logger name="org.springframework.ui.context.support">
> +               <level value="WARN" />
> +       </logger>
> +       <logger name="org.springframework.web.context">
> +               <level value="INFO" />
> +       </logger>
> +       <logger name="org.springframework.web.context.support">
> +               <level value="WARN" />
> +       </logger>
> +       <logger name="org.quartz">
> +               <level value="WARN" />
> +       </logger>
> +       <!-- Caching -->
> +       <logger name="net.sf.ehcache">
> +               <level value="INFO" />
> +       </logger>
> +       <logger name="ch.qos">
> +               <level value="WARN" />
> +       </logger>
> +</configuration>
>
> Modified: incubator/openmeetings/trunk/singlewebapp/build.xml
> URL:
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/build.xml?rev=1306748&r1=1306747&r2=1306748&view=diff
>
> ==============================================================================
> --- incubator/openmeetings/trunk/singlewebapp/build.xml (original)
> +++ incubator/openmeetings/trunk/singlewebapp/build.xml Thu Mar 29
> 08:14:45 2012
> @@ -35,7 +35,7 @@
>        <property name="mainlibs.lib.dir"
> value="${project.lib.dir}/mainlibs" />
>        <property name="om.lib.dir" value="${project.lib.dir}/om" />
>        <property name="anakia.lib.dir" value="${project.lib.dir}/anakia" />
> -       <property name="red5-screenshare.images"
> value="${basedir}/WebContent/red5-screenshare" />
> +       <property name="red5-screenshare.resources"
> value="${basedir}/WebContent/red5-screenshare" />
>        <property name="junit.lib.dir" value="${project.lib.dir}/junit" />
>        <property name="rat.lib.dir" value="${project.lib.dir}/rat" />
>        <property name="dtd-generator.lib.dir"
> value="${project.lib.dir}/dtd-generator" />
> @@ -294,7 +294,7 @@
>                        <fileset dir="${main.out.dir}">
>                                <include name="org/red5/screen/**" />
>                        </fileset>
> -                       <fileset file="${red5.lib}/conf/logback.xml"/>
> +                       <fileset
> file="${red5-screenshare.resources}/logback.xml"/>
>                        <manifest>
>                                <attribute name="Built-By"
> value="OpenMeetings - http://openmeetings.googlecode.com" />
>                                <attribute name="Built-On"
> value="${build.TODAY}" />
> @@ -321,7 +321,7 @@
>                        </dname>
>                </genkey>
>                <copy todir="${screenshare.out.dir}" filtering="true">
> -                       <fileset dir="${red5-screenshare.images}" />
> +                       <fileset dir="${red5-screenshare.resources}"
> includes="*.jpg"/>
>                        <fileset dir="${red5.server.lib}"
> includes="commons-codec*.jar" />
>                        <fileset dir="${red5.server.lib}"
> includes="httpclient*.jar" />
>                        <fileset dir="${red5.server.lib}"
> includes="httpcore*.jar" />
>
> Modified:
> incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/installation/ImportInitvalues.java
> URL:
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/installation/ImportInitvalues.java?rev=1306748&r1=1306747&r2=1306748&view=diff
>
> ==============================================================================
> ---
> incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/installation/ImportInitvalues.java
> (original)
> +++
> incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/installation/ImportInitvalues.java
> Thu Mar 29 08:14:45 2012
> @@ -479,8 +479,9 @@ public class ImportInitvalues {
>                cfgManagement.addConfByKey(3, "show.facebook.login", "" +
> 0, null,
>                                "Show Facebook Login");
>
> -               cfgManagement.addConfByKey(3,
> "default.quality.screensharing", "0",
> -                               null, "Default selection in ScreenSharing
> Quality");
> +               cfgManagement.addConfByKey(3,
> "default.quality.screensharing", "1",
> +                                               null,
> +                                               "Default selection in
> ScreenSharing Quality:\n 0 - bigger frame rate, no resize\n 1 - no resize\n
> 2 - size == 1/2 of selected area\n 3 - size == 3/8 of selected area");
>
>                cfgManagement.addConfByKey(3, "default.dashboard.tab", "0",
> null,
>                                "Default selection in Dashboard tabs as
> tab-index-id");
>
> Modified:
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/CommonScreenShare.java
> URL:
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/CommonScreenShare.java?rev=1306748&r1=1306747&r2=1306748&view=diff
>
> ==============================================================================
> ---
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/CommonScreenShare.java
> (original)
> +++
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/CommonScreenShare.java
> Thu Mar 29 08:14:45 2012
> @@ -1,13 +1,11 @@
>  package org.red5.screen.webstart;
>
>  import java.awt.Color;
> -import java.awt.Graphics2D;
>  import java.awt.Image;
>  import java.awt.MouseInfo;
>  import java.awt.Point;
>  import java.awt.PointerInfo;
>  import java.awt.Rectangle;
> -import java.awt.RenderingHints;
>  import java.awt.Robot;
>  import java.awt.Toolkit;
>  import java.awt.datatransfer.Clipboard;
> @@ -22,14 +20,10 @@ import java.awt.event.KeyEvent;
>  import java.awt.event.WindowAdapter;
>  import java.awt.event.WindowEvent;
>  import java.awt.image.BufferedImage;
> -import java.awt.image.DataBuffer;
> -import java.io.ByteArrayOutputStream;
>  import java.io.IOException;
> -import java.io.OutputStream;
>  import java.util.HashMap;
>  import java.util.Iterator;
>  import java.util.Map;
> -import java.util.zip.DeflaterOutputStream;
>
>  import javax.imageio.ImageIO;
>  import javax.swing.ImageIcon;
> @@ -45,6 +39,7 @@ import org.red5.io.ITagWriter;
>  import org.red5.io.utils.ObjectMap;
>  import org.red5.screen.webstart.gui.VirtualScreen;
>  import org.red5.screen.webstart.gui.VirtualScreenBean;
> +import org.red5.screen.webstart.gui.VirtualScreenBean.ScreenQuality;
>  import org.red5.server.api.event.IEvent;
>  import org.red5.server.api.service.IPendingServiceCall;
>  import org.red5.server.net.rtmp.Channel;
> @@ -117,7 +112,7 @@ public class CommonScreenShare {
>        public String host = "btg199251";
>        public String app = "oflaDemo";
>        public int port = 1935;
> -       public int defaultQualityScreensharing = 0;
> +       public int defaultQualityScreensharing = 1;
>
>        public Long organization_id = 0L;
>        public Long user_id = null;
> @@ -157,11 +152,7 @@ public class CommonScreenShare {
>        public String label1092 = "Medium Quality -";
>        public String label1093 = "Low Quality -";
>
> -       public Float imgQuality = new Float(0.40);
> -
> -       // public Float scaleFactor = 1F;
> -       public float Ampl_factor = 1.3f;
> -
> +       public float Ampl_factor = 1f;
>        public boolean isConnected = false;
>
>        public Map<Integer, Boolean> currentPressedKeys = new
> HashMap<Integer, Boolean>();
> @@ -179,6 +170,9 @@ public class CommonScreenShare {
>        public void main(String[] args) {
>                try {
>                        if (args.length == 9) {
> +                               for (String arg : args) {
> +                                       logger.debug("arg: " + arg);
> +                               }
>
>                                host = args[0];
>                                app = args[1];
> @@ -308,13 +302,6 @@ public class CommonScreenShare {
>                        // *****
>                        // Text Recording
>                        textAreaHeaderRecording = new JLabel();
> -
> -                       // FIXME: Set Font to bold
> -                       // textAreaHeaderRecording.setB
> -                       // Font f = textAreaHeaderRecording.getFont();
> -                       //
> textAreaHeaderRecording.setFont(f.deriveFont(f.getStyle() ^
> -                       // Font.BOLD));
> -
>                        textAreaHeaderRecording.setText(this.label869);
>                        contentPane.add(textAreaHeaderRecording);
>                        textAreaHeaderRecording.setBounds(10, 340, 480, 24);
> @@ -421,9 +408,6 @@ public class CommonScreenShare {
>                        PointerInfo a = MouseInfo.getPointerInfo();
>                        Point mouseP = a.getLocation();
>
> -                       // Integer x =
> Long.valueOf(Math.round(mouseP.getX())).intValue();
> -                       // Integer y =
> Long.valueOf(Math.round(mouseP.getY())).intValue();
> -
>                        Float scaleFactor =
> Float.valueOf(VirtualScreenBean.vScreenResizeX)
>                                        /
> Float.valueOf(VirtualScreenBean.vScreenSpinnerWidth);
>
> @@ -643,18 +627,6 @@ public class CommonScreenShare {
>
>                                // VirtualScreenBean
>
> -                               // Integer x = Math.round ( ( (
> -                               //
> Float.valueOf(returnMap.get("x").toString()).floatValue()
> -                               // *VirtualScreenBean.vScreenResizeX
> -                               //
> )/VirtualScreenBean.vScreenSpinnerWidth) / Ampl_factor) ;
> -                               // Integer y = Math.round ( ( (
> -                               //
> Float.valueOf(returnMap.get("y").toString()).floatValue()
> -                               // *VirtualScreenBean.vScreenResizeY
> -                               //
> )/VirtualScreenBean.vScreenSpinnerHeight)/ Ampl_factor) ;
> -                               //
> -
> -                               // logger.debug("x 1 "+returnMap.get("x"));
> -
>                                Float scaleFactor = Float
>
>  .valueOf(VirtualScreenBean.vScreenSpinnerWidth)
>                                                /
> Float.valueOf(VirtualScreenBean.vScreenResizeX);
> @@ -951,13 +923,10 @@ public class CommonScreenShare {
>                        ex.printStackTrace();
>                }
>                return "";
> -               // clippy.setContents( clippysContent ,null);
> //zur�cksetzen vom alten
> -               // Kontext
>        }
>
>        private void pressSpecialSign(String charValue, Robot instance) {
>                Clipboard clippy =
> Toolkit.getDefaultToolkit().getSystemClipboard();
> -               // Transferable clippysContent = clippy.getContents( null
> );
>                try {
>
>                        Transferable transferableText = new
> StringSelection(charValue);
> @@ -1042,7 +1011,7 @@ public class CommonScreenShare {
>                                        logger.debug("The Stream was
> already started ");
>                                }
>
> -                               if (returnMap.get("modus") != null) {
> +                               if (returnMap != null &&
> returnMap.get("modus") != null) {
>                                        if
> (returnMap.get("modus").toString()
>
>  .equals("startStreaming")) {
>
>  this.startButton.setEnabled(false);
> @@ -1076,12 +1045,7 @@ public class CommonScreenShare {
>                                logger.debug("setup capture thread
> vScreenSpinnerHeight "
>                                                +
> VirtualScreenBean.vScreenSpinnerHeight);
>
> -                               capture = new
> CaptureScreen(VirtualScreenBean.vScreenSpinnerX,
> -
> VirtualScreenBean.vScreenSpinnerY,
> -
> VirtualScreenBean.vScreenSpinnerWidth,
> -
> VirtualScreenBean.vScreenSpinnerHeight,
> -
> VirtualScreenBean.vScreenResizeX,
> -
> VirtualScreenBean.vScreenResizeY);
> +                               capture = new CaptureScreen();
>
>                                if (thread == null) {
>                                        thread = new Thread(capture);
> @@ -1154,11 +1118,6 @@ public class CommonScreenShare {
>
>                kt++;
>
> -               // if ( kt < 10 ) {
> -               // logger.debug( "+++ " + videoData );
> -               // System.out.println( "+++ " + videoData);
> -               // }
> -
>                RTMPMessage rtmpMsg = RTMPMessage.build(videoData);
>                instance.publishStreamData(publishStreamId, rtmpMsg);
>        }
> @@ -1170,14 +1129,6 @@ public class CommonScreenShare {
>        //
> ------------------------------------------------------------------------
>
>        private final class CaptureScreen extends Object implements
> Runnable {
> -               private volatile int x = 0;
> -               private volatile int y = 0;
> -               private volatile int resizeX;
> -               private volatile int resizeY;
> -
> -               private volatile int width = resizeX; // 320
> -               private volatile int height = resizeY; // 240
> -
>                private int timeBetweenFrames = 1000; // frameRate
>
>                private volatile long timestamp = 0;
> @@ -1185,7 +1136,7 @@ public class CommonScreenShare {
>                private volatile boolean active = true;
>                @SuppressWarnings("unused")
>                private volatile boolean stopped = false;
> -               private byte[] previousItems = null;
> +               private IScreenEncoder se;
>
>                //
> ------------------------------------------------------------------------
>                //
> @@ -1193,27 +1144,9 @@ public class CommonScreenShare {
>                //
>                //
> ------------------------------------------------------------------------
>
> -               public CaptureScreen(final int x, final int y, final int
> width,
> -                               final int height, int resizeX, int
> resizeY) {
> -
> -                       this.x = x;
> -                       this.y = y;
> -                       this.width = width;
> -                       this.height = height;
> -                       this.resizeX = resizeX;
> -                       this.resizeY = resizeY;
> -
> -                       if (VirtualScreenBean.vScreenScaleFactor
> -                                       .equals(label1090)) {
> -                               timeBetweenFrames = 100;
> -                       } else {
> -                               timeBetweenFrames = 1000;
> -                       }
> -
> -                       logger.debug("CaptureScreen: x=" + x + ", y=" + y
> + ", w=" + width
> -                                       + ", h=" + height + ",resizeX=" +
> resizeX + " resizeY= "
> -                                       + resizeY);
> -
> +               public CaptureScreen() {
> +                       timeBetweenFrames =
> (VirtualScreenBean.screenQuality == ScreenQuality.VeryHigh) ? 100 : 1000;
> +                       se = new ScreenV1Encoder();
>                }
>
>                //
> ------------------------------------------------------------------------
> @@ -1234,7 +1167,7 @@ public class CommonScreenShare {
>                }
>
>                public void resetBuffer() {
> -                       this.previousItems = null;
> +                       se.reset();
>                }
>
>                //
> ------------------------------------------------------------------------
> @@ -1242,89 +1175,27 @@ public class CommonScreenShare {
>                // Thread loop
>                //
>                //
> ------------------------------------------------------------------------
> -
>                public void run() {
> -                       final int blockWidth = 32;
> -                       final int blockHeight = 32;
> -
> -                       int frameCounter = 0;
> -
> -                       int orig_width = width;
> -                       int orig_height = height;
> -
>                        try {
>                                Robot robot = new Robot();
>
> -                               this.previousItems = null;
> -
>                                while (active) {
>                                        final long ctime =
> System.currentTimeMillis();
>
> -                                       width = orig_width;
> -                                       height = orig_height;
> -
> -                                       BufferedImage image = robot
> -
> .createScreenCapture(new Rectangle(x, y, width,
> -
> height));
> -
> -                                       int width_new = resizeX;
> -                                       int height_new = resizeY;
> -                                       width = resizeX;
> -                                       height = resizeY;
> -                                       // Resize to 640*480
> -                                       // Create new (blank) image of
> required (scaled) size
> -                                       BufferedImage image_raw = new
> BufferedImage(width_new,
> -                                                       height_new,
> BufferedImage.TYPE_INT_RGB);
> -
> -                                       Graphics2D graphics2D =
> image_raw.createGraphics();
> -                                       graphics2D.setRenderingHint(
> -
> RenderingHints.KEY_INTERPOLATION,
> -
> RenderingHints.VALUE_INTERPOLATION_BICUBIC);
> -                                       graphics2D.drawImage(image, 0, 0,
> width_new, height_new,
> -                                                       null);
> -                                       graphics2D.dispose();
> -
> -                                       // End resize
> -
> -                                       int scaledWidth = width;
> -                                       int scaledHeight = height;
> -
> -                                       byte[] current = toBGR(image_raw);
> -                                       // if (scaleFactor != 1F) {
> -                                       //
> -                                       // logger.debug("Calc new Scaled
> Instance ",scaleFactor);
> -                                       //
> -                                       // scaledWidth =
> -                                       //
> Float.valueOf(Math.round(width*scaleFactor)).intValue();
> -                                       // scaledHeight =
> -                                       //
> Float.valueOf(Math.round(height*scaleFactor)).intValue();
> -                                       //
> -                                       // Image img =
> image_raw.getScaledInstance(scaledWidth,
> -                                       //
> scaledHeight,Image.SCALE_SMOOTH);
> -                                       //
> -                                       // BufferedImage image_scaled = new
> -                                       // BufferedImage(scaledWidth,
> -                                       //
> scaledHeight,BufferedImage.TYPE_3BYTE_BGR);
> -                                       //
> -                                       // Graphics2D biContext =
> image_scaled.createGraphics();
> -                                       // biContext.drawImage(img, 0, 0,
> null);
> -                                       // current = toBGR(image_scaled);
> -                                       // } else {
> -                                       // current = toBGR(image_raw);
> -                                       // }
> +                                       Rectangle screen = new
> Rectangle(VirtualScreenBean.vScreenSpinnerX,
> +
> VirtualScreenBean.vScreenSpinnerY,
> +
> VirtualScreenBean.vScreenSpinnerWidth,
> +
> VirtualScreenBean.vScreenSpinnerHeight);
> +
> +                                       BufferedImage image =
> robot.createScreenCapture(screen);
>
>                                        try {
> -                                               // timestamp += (1000000 /
> timeBetweenFrames);
>                                                timestamp +=
> timeBetweenFrames;
>
> -                                               final byte[] screenBytes =
> encode(current,
> -
> this.previousItems, blockWidth, blockHeight,
> -
> scaledWidth, scaledHeight);
> -
> pushVideo(screenBytes.length, screenBytes, timestamp);
> -                                               this.previousItems =
> current;
> +                                               byte[] data =
> se.encode(screen, image, new Rectangle(VirtualScreenBean.vScreenResizeX,
> +
> VirtualScreenBean.vScreenResizeY));
>
> -                                               if (++frameCounter % 100
> == 0)
> -                                                       this.previousItems
> = null;
> +                                               pushVideo(data.length,
> data, timestamp);
>                                        } catch (Exception e) {
>                                                e.printStackTrace();
>                                        }
> @@ -1339,132 +1210,5 @@ public class CommonScreenShare {
>                                e.printStackTrace();
>                        }
>                }
> -
> -               //
> ------------------------------------------------------------------------
> -               //
> -               // Private
> -               //
> -               //
> ------------------------------------------------------------------------
> -
> -               private byte[] toBGR(BufferedImage image) {
> -                       final int width = image.getWidth();
> -                       final int height = image.getHeight();
> -
> -                       byte[] buf = new byte[3 * width * height];
> -
> -                       final DataBuffer buffer =
> image.getData().getDataBuffer();
> -
> -                       for (int y = 0; y < height; y++) {
> -                               for (int x = 0; x < width; x++) {
> -                                       final int rgb = buffer.getElem(y *
> width + x);
> -                                       final int offset = 3 * (y * width
> + x);
> -
> -                                       buf[offset + 0] = (byte) (rgb &
> 0xFF);
> -                                       buf[offset + 1] = (byte) ((rgb >>
> 8) & 0xFF);
> -                                       buf[offset + 2] = (byte) ((rgb >>
> 16) & 0xFF);
> -                               }
> -                       }
> -
> -                       return buf;
> -               }
> -
> -               private byte[] encode(final byte[] current, final byte[]
> previous,
> -                               final int blockWidth, final int
> blockHeight, final int width,
> -                               final int height) throws Exception {
> -                       ByteArrayOutputStream baos = new
> ByteArrayOutputStream(16 * 1024);
> -
> -                       if (previous == null) {
> -                               baos.write(getTag(0x01, 0x03)); //
> keyframe (all cells)
> -                       } else {
> -                               baos.write(getTag(0x02, 0x03)); // frame
> (changed cells)
> -                       }
> -
> -                       // write header
> -                       final int wh = width + ((blockWidth / 16 - 1) <<
> 12);
> -                       final int hh = height + ((blockHeight / 16 - 1) <<
> 12);
> -
> -                       writeShort(baos, wh);
> -                       writeShort(baos, hh);
> -
> -                       // write content
> -                       int y0 = height;
> -                       int x0 = 0;
> -                       int bwidth = blockWidth;
> -                       int bheight = blockHeight;
> -
> -                       while (y0 > 0) {
> -                               bheight = Math.min(y0, blockHeight);
> -                               y0 -= bheight;
> -
> -                               bwidth = blockWidth;
> -                               x0 = 0;
> -
> -                               while (x0 < width) {
> -                                       bwidth = (x0 + blockWidth > width)
> ? width - x0
> -                                                       : blockWidth;
> -
> -                                       final boolean changed =
> isChanged(current, previous, x0,
> -                                                       y0, bwidth,
> bheight, width, height);
> -
> -                                       if (changed) {
> -                                               ByteArrayOutputStream
> blaos = new ByteArrayOutputStream(
> -                                                               4 * 1024);
> -
> -                                               DeflaterOutputStream dos =
> new DeflaterOutputStream(
> -                                                               blaos);
> -
> -                                               for (int y = 0; y <
> bheight; y++) {
> -                                                       dos.write(current,
> 3 * ((y0 + bheight - y - 1)
> -                                                                       *
> width + x0), 3 * bwidth);
> -                                               }
> -
> -                                               dos.finish();
> -
> -                                               final byte[] bbuf =
> blaos.toByteArray();
> -                                               final int written =
> bbuf.length;
> -
> -                                               // write DataSize
> -                                               writeShort(baos, written);
> -                                               // write Data
> -                                               baos.write(bbuf, 0,
> written);
> -                                       } else {
> -                                               // write DataSize
> -                                               writeShort(baos, 0);
> -                                       }
> -
> -                                       x0 += bwidth;
> -                               }
> -                       }
> -
> -                       return baos.toByteArray();
> -               }
> -
> -               private void writeShort(OutputStream os, final int n)
> throws Exception {
> -                       os.write((n >> 8) & 0xFF);
> -                       os.write((n >> 0) & 0xFF);
> -               }
> -
> -               public boolean isChanged(final byte[] current, final
> byte[] previous,
> -                               final int x0, final int y0, final int
> blockWidth,
> -                               final int blockHeight, final int width,
> final int height) {
> -                       if (previous == null)
> -                               return true;
> -
> -                       for (int y = y0, ny = y0 + blockHeight; y < ny;
> y++) {
> -                               final int foff = 3 * (x0 + width * y);
> -                               final int poff = 3 * (x0 + width * y);
> -
> -                               for (int i = 0, ni = 3 * blockWidth; i <
> ni; i++) {
> -                                       if (current[foff + i] !=
> previous[poff + i])
> -                                               return true;
> -                               }
> -                       }
> -
> -                       return false;
> -               }
> -
> -               public int getTag(final int frame, final int codec) {
> -                       return ((frame & 0x0F) << 4) + ((codec & 0x0F) <<
> 0);
> -               }
>        }
>  }
>
> Added:
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/IScreenEncoder.java
> URL:
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/IScreenEncoder.java?rev=1306748&view=auto
>
> ==============================================================================
> ---
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/IScreenEncoder.java
> (added)
> +++
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/IScreenEncoder.java
> Thu Mar 29 08:14:45 2012
> @@ -0,0 +1,30 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements.  See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership.  The ASF licenses this file
> + * to you under the Apache License, Version 2.0 (the
> + * "License") +  you may not use this file except in compliance
> + * with the License.  You may obtain a copy of the License at
> + *
> + *   http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,
> + * software distributed under the License is distributed on an
> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + * KIND, either express or implied.  See the License for the
> + * specific language governing permissions and limitations
> + * under the License.
> + */
> +package org.red5.screen.webstart;
> +
> +import java.awt.Rectangle;
> +import java.awt.image.BufferedImage;
> +import java.io.IOException;
> +
> +public interface IScreenEncoder {
> +
> +       byte[] encode(Rectangle screen, BufferedImage img, Rectangle size)
>  throws IOException;
> +
> +       void reset();
> +}
>
> Added:
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/ScreenV1Encoder.java
> URL:
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/ScreenV1Encoder.java?rev=1306748&view=auto
>
> ==============================================================================
> ---
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/ScreenV1Encoder.java
> (added)
> +++
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/ScreenV1Encoder.java
> Thu Mar 29 08:14:45 2012
> @@ -0,0 +1,146 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements.  See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership.  The ASF licenses this file
> + * to you under the Apache License, Version 2.0 (the
> + * "License") +  you may not use this file except in compliance
> + * with the License.  You may obtain a copy of the License at
> + *
> + *   http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,
> + * software distributed under the License is distributed on an
> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + * KIND, either express or implied.  See the License for the
> + * specific language governing permissions and limitations
> + * under the License.
> + */
> +package org.red5.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;
> +
> +public class ScreenV1Encoder implements IScreenEncoder {
> +       private BufferedImage last = null;
> +       private static int KEY_FRAME_INDEX = 100;
> +       private static int DEFAULT_BLOCK_SIZE = 32;
> +       private int keyFrameIndex;
> +       private int frameCount = 0;
> +       private int blockSize;
> +       private Rectangle screen;
> +
> +       public ScreenV1Encoder() {
> +               this(KEY_FRAME_INDEX, DEFAULT_BLOCK_SIZE);
> +       }
> +
> +       //will create square blocks
> +       public ScreenV1Encoder(int keyFrameIndex, int blockSize) {
> +               this.keyFrameIndex = keyFrameIndex;
> +               if (blockSize < 16 || blockSize > 256 || blockSize % 16 !=
> 0) {
> +                       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;
> +       }
> +
> +       public byte[] encode(Rectangle screen, BufferedImage _img,
> Rectangle size) throws IOException {
> +               BufferedImage img = resize(_img, size);
> +               Rectangle imgArea = new Rectangle(img.getWidth(),
> img.getHeight());
> +               Rectangle area = getNextBlock(imgArea, null);
> +               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));
> +               writeShort(ba, imgArea.height + ((blockSize / 16 - 1) <<
> 12));
> +
> +               while (area.width > 0 && area.height > 0) {
> +                       writeBytesIfChanged(ba, isKeyFrame, img, area);
> +                       area = getNextBlock(imgArea, area);
> +               }
> +               this.screen = screen;
> +               last = img;
> +               return ba.toByteArray();
> +       }
> +
> +       public void reset() {
> +               last = null;
> +       }
> +
> +       private Rectangle getNextBlock(Rectangle img, Rectangle _prev) {
> +               Rectangle prev;
> +               if (_prev == null) {
> +                       prev = new Rectangle(0, Math.max(0, img.height -
> blockSize), blockSize, blockSize);
> +               } else {
> +                       prev = new Rectangle(_prev);
> +                       if (prev.x + prev.width == img.getWidth()) {
> +                               if (prev.y == 0) return new Rectangle();
> //the end of the image
> +                               //next row
> +                               prev.x = 0; //reset position
> +                               prev.width = blockSize; //reset width
> +                               prev.y -= (prev.y > blockSize ? blockSize
> : prev.y);
> +                       } else {
> +                               prev.x += blockSize;
> +                       }
> +               }
> +               return img.intersection(prev);
> +       }
> +
> +       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);
> +               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
> +                               });
> +                       }
> +               }
> +               dos.finish();
> +               if (changed) {
> +                       final int written = baos.size();
> +                       writeShort(ba, written);
> +                       ba.write(baos.toByteArray(), 0, written);
> +               } else {
> +                       writeShort(ba, 0);
> +               }
> +       }
> +
> +       public int getTag(final int frame, final int codec) {
> +               return ((frame & 0x0F) << 4) + ((codec & 0x0F) << 0);
> +       }
> +
> +       private void writeShort(OutputStream os, final int n) throws
> IOException {
> +               os.write((n >> 8) & 0xFF);
> +               os.write((n >> 0) & 0xFF);
> +       }
> +}
>
> Modified:
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreen.java
> URL:
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreen.java?rev=1306748&r1=1306747&r2=1306748&view=diff
>
> ==============================================================================
> ---
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreen.java
> (original)
> +++
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreen.java
> Thu Mar 29 08:14:45 2012
> @@ -18,27 +18,29 @@
>  */
>  package org.red5.screen.webstart.gui;
>
> -import javax.imageio.ImageIO;
>  import java.awt.Color;
>  import java.awt.Dimension;
>  import java.awt.Image;
>  import java.awt.Rectangle;
>  import java.awt.Robot;
> +import java.awt.event.ActionEvent;
> +import java.awt.event.ActionListener;
>  import java.awt.image.BufferedImage;
>
> -import javax.swing.SwingConstants;
> +import javax.imageio.ImageIO;
>  import javax.swing.ImageIcon;
> -import javax.swing.JLabel;
>  import javax.swing.JComboBox;
> +import javax.swing.JLabel;
>  import javax.swing.JSpinner;
>  import javax.swing.SpinnerNumberModel;
> +import javax.swing.SwingConstants;
>  import javax.swing.event.ChangeEvent;
>  import javax.swing.event.ChangeListener;
> -import java.awt.event.*;
>
>  import org.red5.screen.webstart.BlankArea;
>  import org.red5.screen.webstart.CommonScreenShare;
>  import org.red5.screen.webstart.ScreenShare;
> +import org.red5.screen.webstart.gui.VirtualScreenBean.ScreenQuality;
>  import org.slf4j.Logger;
>  import org.slf4j.LoggerFactory;
>
> @@ -50,6 +52,40 @@ public class VirtualScreen {
>
>        public boolean doUpdateBounds = true;
>
> +       private class KeyValue<T> {
> +               private String key;
> +               private T value;
> +
> +               public KeyValue(String key, T value) {
> +                       this.key = key;
> +                       this.value = value;
> +               }
> +
> +               @SuppressWarnings("unused")
> +               public String getKey() { return key; }
> +               public T getValue() { return value; }
> +
> +               @Override
> +               public String toString() { return key; }
> +
> +               @Override
> +               public boolean equals(Object obj) {
> +                       if (obj instanceof KeyValue) {
> +                               @SuppressWarnings("unchecked")
> +                               KeyValue<T> kv = (KeyValue<T>) obj;
> +                               return (kv.value.equals(this.value));
> +                       }
> +                       return false;
> +               }
> +
> +               @Override
> +               public int hashCode() {
> +                       int hash = 7;
> +                       hash = 97 * hash + (this.value != null ?
> this.value.hashCode() : 0);
> +                       return hash;
> +               }
> +       }
> +
>        public VirtualScreen(CommonScreenShare css) throws Exception {
>                this.css = css;
>
> @@ -175,7 +211,6 @@ public class VirtualScreen {
>                css.jVScreenXSpin.setBounds(400, 170, 60, 24);
>                css.jVScreenXSpin.addChangeListener( new ChangeListener(){
>                        public void stateChanged(ChangeEvent arg0) {
> -                               // TODO Auto-generated method stub
>                                calcNewValueXSpin();
>                        }
>                });
> @@ -194,7 +229,6 @@ public class VirtualScreen {
>                css.jVScreenYSpin.setBounds(400, 200, 60, 24);
>                css.jVScreenYSpin.addChangeListener( new ChangeListener(){
>                        public void stateChanged(ChangeEvent arg0) {
> -                               // TODO Auto-generated method stub
>                                calcNewValueYSpin();
>                        }
>                });
> @@ -213,7 +247,6 @@ public class VirtualScreen {
>                css.jVScreenWidthSpin.setBounds(400, 240, 60, 24);
>                css.jVScreenWidthSpin.addChangeListener( new
> ChangeListener(){
>                        public void stateChanged(ChangeEvent arg0) {
> -                               // TODO Auto-generated method stub
>                                calcNewValueWidthSpin();
>                        }
>                });
> @@ -232,15 +265,12 @@ public class VirtualScreen {
>                css.jVScreenHeightSpin.setBounds(400, 270, 60, 24);
>                css.jVScreenHeightSpin.addChangeListener( new
> ChangeListener(){
>                        public void stateChanged(ChangeEvent arg0) {
> -                               // TODO Auto-generated method stub
>                                calcNewValueHeightSpin();
>                        }
>                });
>                css.t.add(css.jVScreenHeightSpin);
>
>
> -               //String[] selectResize = { css.label1090, css.label1091,
> css.label1092, css.label1093 };
> -               String[] selectResize = { css.label1091, css.label1092,
> css.label1093 };
>                VirtualScreenBean.vScreenResizeX = 640;
>                VirtualScreenBean.vScreenResizeY = 400;
>
> @@ -249,84 +279,55 @@ public class VirtualScreen {
>                css.vscreenResizeLabel.setBounds(250, 300, 200,24 );
>                css.t.add(css.vscreenResizeLabel);
>
> -               JComboBox comboResize  = new JComboBox(selectResize);
> +               JComboBox comboResize  = new JComboBox();
> +               comboResize.addItem(new
> KeyValue<ScreenQuality>(css.label1090, ScreenQuality.VeryHigh));
> +               comboResize.addItem(new
> KeyValue<ScreenQuality>(css.label1091, ScreenQuality.High));
> +               comboResize.addItem(new
> KeyValue<ScreenQuality>(css.label1092, ScreenQuality.Medium));
> +               comboResize.addItem(new
> KeyValue<ScreenQuality>(css.label1093, ScreenQuality.Low));
>                comboResize.setBounds(250, 330, 200, 24);
> -               comboResize.addActionListener(new GetResizeChoice());
> +               comboResize.addActionListener(new ActionListener(){
> +                       @SuppressWarnings("unchecked")
> +                       public void actionPerformed(ActionEvent e) {
> +                               JComboBox cb = (JComboBox)e.getSource();
> +                       VirtualScreenBean.screenQuality =
> ((KeyValue<ScreenQuality>)cb.getSelectedItem()).getValue();
> +                       calcRescaleFactors();
> +                       }
> +               });
>
>  comboResize.setSelectedIndex(css.defaultQualityScreensharing);
>
>                css.jVScreenResizeMode = comboResize;
>                css.t.add(css.jVScreenResizeMode);
>
>        }
> -       class GetResizeChoice implements ActionListener
> -       {
> -               public void actionPerformed (ActionEvent e)
> -               {
> -
> -                       JComboBox cb = (JComboBox)e.getSource();
> -               String petName = (String)cb.getSelectedItem();
> -
> -               VirtualScreenBean.vScreenScaleFactor = petName;
> -
> -               calcRescaleFactors();
> -
> -               }
> -       }
>
>        /**
>         * Needs to be always invoked after every re-scaling
>         */
>        void calcRescaleFactors() {
> -
>                logger.debug("calcRescaleFactors -- ");
> -
> if(VirtualScreenBean.vScreenScaleFactor.equals(css.label1090))
> -        {
> -                       logger.debug("resize:
> X:"+Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue()+
> -                                       "
> Y:"+Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue());
> -
> -                       VirtualScreenBean.vScreenResizeX =
> Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue();
> -                       VirtualScreenBean.vScreenResizeY =
> Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue();
> -                       updateVScreenBounds();
> -        }
> -               else
> if(VirtualScreenBean.vScreenScaleFactor.equals(css.label1091))
> -        {
> -               logger.debug("resize:
> X:"+Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue()+
> -                                                       "
> Y:"+Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue());
> -
> -               VirtualScreenBean.vScreenResizeX =
> Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue();
> -               VirtualScreenBean.vScreenResizeY =
> Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue();
> -               updateVScreenBounds();
> -        }
> -        else
> if(VirtualScreenBean.vScreenScaleFactor.equals(css.label1092))
> -        {
> -               logger.debug("resize:
> X:"+Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue()/2+
> -                                                       "
> Y:"+Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue()/2);
> -
> -               VirtualScreenBean.vScreenResizeX =
> (Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue())/2;
> -               VirtualScreenBean.vScreenResizeY =
> (Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue())/2;
> -               updateVScreenBounds();
> -        }
> -        else
> if(VirtualScreenBean.vScreenScaleFactor.equals(css.label1093))
> -        {
> -               logger.debug("resize:
> X:"+(Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue()/8)*3+
> -                                                       "
> Y:"+(Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue()/8)*3);
> -
> -               VirtualScreenBean.vScreenResizeX =
> (Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue()/8)*3;
> -               VirtualScreenBean.vScreenResizeY =
> (Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue()/8)*3;
> -               updateVScreenBounds();
> -        }
> -
> -                logger.debug("########## calcRescaleFactors
> vScreenResizeX " + VirtualScreenBean.vScreenResizeX);
> -         logger.debug("########## calcRescaleFactors vScreenResizeY " +
> VirtualScreenBean.vScreenResizeY);
> -         logger.debug("########## calcRescaleFactors vScreenScaleFactor "
> + VirtualScreenBean.vScreenScaleFactor);
> -
> +               VirtualScreenBean.vScreenResizeX =
> Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue();
> +               VirtualScreenBean.vScreenResizeY =
> Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue();
> +               switch (VirtualScreenBean.screenQuality) {
> +                       case VeryHigh:
> +                       case High:
> +                               break;
> +                       case Medium:
> +                               VirtualScreenBean.vScreenResizeX *= 1/2;
> +                               VirtualScreenBean.vScreenResizeY *= 2;
> +                               break;
> +                       case Low:
> +                               VirtualScreenBean.vScreenResizeX *= 3/8;
> +                               VirtualScreenBean.vScreenResizeY *= 3/8;
> +                               break;
> +               }
> +               logger.debug("resize: X:" +
> VirtualScreenBean.vScreenResizeX + " Y: " +
> VirtualScreenBean.vScreenResizeY);
> +               updateVScreenBounds();
>        }
>
>        void calcNewValueXSpin(){
>                if (this.doUpdateBounds){
>                        int newX =
> Integer.valueOf(css.jVScreenXSpin.getValue().toString()).intValue();
>                        if(VirtualScreenBean.vScreenSpinnerWidth+newX >
> VirtualScreenBean.screenWidthMax){
> -//                             System.out.println("WARNING X
> "+VirtualScreenBean.vScreenSpinnerWidth+" "+newX);
>
>  newX=VirtualScreenBean.screenWidthMax-VirtualScreenBean.vScreenSpinnerWidth;
>                                css.jVScreenXSpin.setValue(newX);
>                                if (this.showWarning)
> css.showBandwidthWarning("Reduce the width of the SharingScreen before you
> try to move it left");
> @@ -363,7 +364,6 @@ public class VirtualScreen {
>                if (this.doUpdateBounds){
>                        int newWidth =
> Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue();
>                        if(VirtualScreenBean.vScreenSpinnerX+newWidth >
> VirtualScreenBean.screenWidthMax){
> -//                             System.out.println("WARNING WIDTH");
>
>  newWidth=VirtualScreenBean.screenWidthMax-VirtualScreenBean.vScreenSpinnerX;
>                                css.jVScreenWidthSpin.setValue(newWidth);
>                                if
> (this.showWarning)css.showBandwidthWarning("Reduce the x of the
> SharingScreen before you try to make it wider");
>
> Modified:
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreenBean.java
> URL:
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreenBean.java?rev=1306748&r1=1306747&r2=1306748&view=diff
>
> ==============================================================================
> ---
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreenBean.java
> (original)
> +++
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreenBean.java
> Thu Mar 29 08:14:45 2012
> @@ -18,11 +18,8 @@
>  */
>  package org.red5.screen.webstart.gui;
>
> -import java.awt.Robot;
>
>  public class VirtualScreenBean {
> -
> -
>        /**
>         * image recalcing value's from the virtual Screen drawer
>         */
> @@ -47,13 +44,15 @@ public class VirtualScreenBean {
>        public static int vScreenSpinnerX = 0;
>        public static int vScreenSpinnerY = 0;
>
> -       public static String vScreenScaleFactor = "Medium Quality";
> +       public static ScreenQuality screenQuality = ScreenQuality.Medium;
>
>        public static int vScreenResizeX = 480;
>        public static int vScreenResizeY = 360;
>
> -
> -       public static Robot robot = null;
> -
> -       public static Float imgQuality = new Float(0.40);
> +       public enum ScreenQuality {
> +               VeryHigh
> +               , High
> +               , Medium
> +               , Low
> +       }
>  }
>
>
>


-- 
Sebastian Wagner
https://twitter.com/#!/dead_lock
http://www.openmeetings.de <http://incubator.apache.org/openmeetings/>
http://www.webbase-design.de
http://www.wagner-sebastian.com
seba.wagner@gmail.com

Re: svn commit: r1306748 - in /incubator/openmeetings/trunk/singlewebapp: ./ WebContent/red5-screenshare/ src/org/openmeetings/app/installation/ src/org/red5/screen/webstart/ src/org/red5/screen/webstart/gui/

Posted by "seba.wagner@gmail.com" <se...@gmail.com>.
I think a good place to ask for help regarding the SHA1 (or potentially
SHA2) algorythm is the FFMPEG list.
There are people at that list that know how to implement it and how it
works as FFMPEG has an implementation for encoder and decoder.
You can also search the internet for "FFMPEG flashsv.c" or "FFMPEG
flashsv2.c"

Sebastian

2012/3/30 Maxim Solodovnik <so...@gmail.com>

> I mean "Screen Video bitstream format" section in
> this swf_file_format_spec_v10.pdf document
> its 2.5 pages not one, but its too general.
>
>
> On Fri, Mar 30, 2012 at 14:08, seba.wagner@gmail.com
> <se...@gmail.com>wrote:
>
> > That would be nice, I have written the code 3-4 years ago so it would be
> > nice if you find the time to refactor it.
> >
> > 1 page of documentation is too few? You mean the part about SHA1 in the
> > RTMP spec ?
> >
> > 2012/3/30 Maxim Solodovnik <so...@gmail.com>
> >
> > > I was able to find _some_ of spec necessary. And was able to "guess"
> > > missing parts (1 page of documentation is too few)
> > >
> > > I'll check Medium and Low quality and rename package + modify the build
> > >
> > > I have changed  1.3 to be 1.0 (no need for upscale IMHO).
> > >
> > > regarding copy/paste:
> > > 1) I don't really like the idea of "static VirtualScreenBean" (it is
> not
> > > bean, there is no need to make it static)
> > > 2) various methods contains lots of similar code:
> > >      a) VirtualScreen.updateVScreenBounds() similar calculations with
> > lots
> > > of casting
> > >      b) CommonScreenShare.sendRemoteCursorEvent similar blocks of code
> > > 3) I don't really like how the code is organized (I'm not 'comfortable'
> > > with it maybe will review it in a spare time)
> > >
> > > On Fri, Mar 30, 2012 at 00:11, seba.wagner@gmail.com
> > > <se...@gmail.com>wrote:
> > >
> > > > Hi Maxim,
> > > >
> > > > nice job :) Have you find something in the Specs for the protocol?
> > > >
> > > > Btw: Sharing or recording with medium or low quality throws some
> > > exception
> > > > now:
> > > > java.lang.IllegalArgumentException: Width (0) and height (2048)
> cannot
> > be
> > > > <= 0
> > > >    at
> > > >
> java.awt.image.DirectColorModel.createCompatibleWritableRaster(Unknown
> > > > Source)
> > > >    at java.awt.image.BufferedImage.<init>(Unknown Source)
> > > >    at
> > > >
> > org.red5.screen.webstart.ScreenV1Encoder.resize(ScreenV1Encoder.java:55)
> > > >    at
> > > >
> > org.red5.screen.webstart.ScreenV1Encoder.encode(ScreenV1Encoder.java:68)
> > > >    at
> > > >
> > > >
> > >
> >
> org.red5.screen.webstart.CommonScreenShare$CaptureScreen.run(CommonScreenShare.java:1195)
> > > >    at java.lang.Thread.run(Unknown Source)
> > > >
> > > > About the quality settings in the client: Did you also change the
> > > "normal"
> > > > (high) quality that it does _not_ rescale the screen anymore?
> > Previously
> > > > the factor was 1.3 for the normal modus. I don't think that this is
> > > > neccessary.
> > > >
> > > > I think we should also fix the the package name to fit into our
> > > structure,
> > > > what do you think?
> > > >
> > > > What did you mean by *The code still need to be reviewed to remove
> > > > copy/pasted code* ?
> > > >
> > > > Thanks!
> > > > Sebastian
> > > >
> > > >
> > > > 2012/3/29 <so...@apache.org>
> > > >
> > > > > Author: solomax
> > > > > Date: Thu Mar 29 08:14:45 2012
> > > > > New Revision: 1306748
> > > > >
> > > > > URL: http://svn.apache.org/viewvc?rev=1306748&view=rev
> > > > > Log:
> > > > > Screen sharing client cleaned up from 'borrowed' code; code cleanup
> > > > >
> > > > > Added:
> > > > >
> > > > >
> > > >
> > >
> >
>  incubator/openmeetings/trunk/singlewebapp/WebContent/red5-screenshare/logback.xml
> > > > >
> > > > >
> > > >
> > >
> >
>  incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/IScreenEncoder.java
> > > > >
> > > > >
> > > >
> > >
> >
>  incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/ScreenV1Encoder.java
> > > > > Modified:
> > > > >    incubator/openmeetings/trunk/singlewebapp/build.xml
> > > > >
> > > > >
> > > >
> > >
> >
>  incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/installation/ImportInitvalues.java
> > > > >
> > > > >
> > > >
> > >
> >
>  incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/CommonScreenShare.java
> > > > >
> > > > >
> > > >
> > >
> >
>  incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreen.java
> > > > >
> > > > >
> > > >
> > >
> >
>  incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreenBean.java
> > > > >
> > > > > Added:
> > > > >
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/WebContent/red5-screenshare/logback.xml
> > > > > URL:
> > > > >
> > > >
> > >
> >
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/WebContent/red5-screenshare/logback.xml?rev=1306748&view=auto
> > > > >
> > > > >
> > > >
> > >
> >
> ==============================================================================
> > > > > ---
> > > > >
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/WebContent/red5-screenshare/logback.xml
> > > > > (added)
> > > > > +++
> > > > >
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/WebContent/red5-screenshare/logback.xml
> > > > > Thu Mar 29 08:14:45 2012
> > > > > @@ -0,0 +1,159 @@
> > > > > +<?xml version="1.0" encoding="UTF-8"?>
> > > > > +<configuration>
> > > > > +       <!-- Uncomment if you are using the logback plugin for
> > eclipse
> > > > > +       <consolePlugin/>
> > > > > +       -->
> > > > > +       <appender name="CONSOLE"
> > > > > class="ch.qos.logback.core.ConsoleAppender">
> > > > > +               <encoder>
> > > > > +                       <pattern>[%p] [%thread] %logger -
> > > > %msg%n</pattern>
> > > > > +               </encoder>
> > > > > +       </appender>
> > > > > +       <root>
> > > > > +               <level value="WARN" />
> > > > > +               <appender-ref ref="CONSOLE" />
> > > > > +       </root>
> > > > > +       <!-- Red5 -->
> > > > > +       <logger name="org.red5.server.Launcher">
> > > > > +               <level value="INFO" />
> > > > > +       </logger>
> > > > > +       <logger name="org.red5.io">
> > > > > +               <level value="INFO" />
> > > > > +       </logger>
> > > > > +    <logger name="org.red5.logging.DerbyLogInterceptor">
> > > > > +        <level value="WARN" />
> > > > > +    </logger>
> > > > > +    <logger name="org.red5.server">
> > > > > +        <level value="WARN" />
> > > > > +    </logger>
> > > > > +       <logger name="org.red5.server.Client">
> > > > > +               <level value="INFO" />
> > > > > +       </logger>
> > > > > +       <logger name="org.red5.server.api.stream.support">
> > > > > +               <level value="INFO" />
> > > > > +       </logger>
> > > > > +       <logger name="org.red5.server.cache">
> > > > > +               <level value="WARN" />
> > > > > +       </logger>
> > > > > +       <logger name="org.red5.server.jmx">
> > > > > +               <level value="WARN" />
> > > > > +       </logger>
> > > > > +       <logger
> > name="org.red5.server.messaging.InMemoryPushPushPipe">
> > > > > +               <level value="INFO" />
> > > > > +       </logger>
> > > > > +       <logger name="org.red5.server.net">
> > > > > +               <level value="INFO" />
> > > > > +       </logger>
> > > > > +       <logger name="org.red5.server.net.rtmpt.RTMPTServlet">
> > > > > +               <level value="WARN" />
> > > > > +       </logger>
> > > > > +       <logger name="org.red5.server.net.servlet">
> > > > > +               <level value="WARN" />
> > > > > +       </logger>
> > > > > +       <logger name="org.red5.server.net.proxy">
> > > > > +               <level value="INFO" />
> > > > > +       </logger>
> > > > > +       <logger name="org.red5.server.net.remoting">
> > > > > +               <level value="WARN" />
> > > > > +       </logger>
> > > > > +       <logger name="org.red5.server.net.rtmp">
> > > > > +               <level value="WARN" />
> > > > > +       </logger>
> > > > > +       <logger name="org.red5.server.net.rtmp.BaseRTMPHandler">
> > > > > +               <level value="WARN" />
> > > > > +       </logger>
> > > > > +       <logger name="org.red5.server.net.rtmp.RTMPMinaIoHandler">
> > > > > +               <level value="WARN" />
> > > > > +       </logger>
> > > > > +       <logger name="org.red5.server.net.rtmp.status">
> > > > > +               <level value="INFO" />
> > > > > +       </logger>
> > > > > +       <logger name="org.red5.server.net.rtmpt">
> > > > > +               <level value="WARN" />
> > > > > +       </logger>
> > > > > +       <logger name="org.red5.server.persistence">
> > > > > +               <level value="WARN" />
> > > > > +       </logger>
> > > > > +       <logger name="org.red5.server.script">
> > > > > +               <level value="WARN" />
> > > > > +       </logger>
> > > > > +       <logger name="org.red5.server.service">
> > > > > +               <level value="INFO" />
> > > > > +       </logger>
> > > > > +       <logger name="org.red5.server.so">
> > > > > +               <level value="WARN" />
> > > > > +       </logger>
> > > > > +       <logger name="org.red5.server.stream">
> > > > > +               <level value="INFO" />
> > > > > +       </logger>
> > > > > +       <logger name="org.red5.server.stream.consumer">
> > > > > +               <level value="WARN" />
> > > > > +       </logger>
> > > > > +       <logger name="org.red5.server.net.mrtmp">
> > > > > +               <level value="WARN" />
> > > > > +       </logger>
> > > > > +       <!-- Mina -->
> > > > > +       <logger name="org.apache.mina">
> > > > > +               <level value="WARN" />
> > > > > +       </logger>
> > > > > +       <logger name="org.apache.mina.filter">
> > > > > +               <level value="WARN" />
> > > > > +       </logger>
> > > > > +       <logger
> > > > > name="org.red5.server.adapter.MultiThreadedApplicationAdapter" >
> > > > > +               <level value="INFO"/>
> > > > > +       </logger>
> > > > > +       <!-- Apache commons -->
> > > > > +       <logger name="org.apache.commons">
> > > > > +               <level value="WARN" />
> > > > > +       </logger>
> > > > > +       <logger name="httpclient">
> > > > > +               <level value="WARN" />
> > > > > +       </logger>
> > > > > +       <!-- Apache catalina / tomcat -->
> > > > > +    <logger name="org.red5.server.tomcat">
> > > > > +        <level value="INFO" />
> > > > > +    </logger>
> > > > > +    <logger name="org.apache.catalina">
> > > > > +        <level value="WARN" />
> > > > > +    </logger>
> > > > > +       <logger name="org.apache.jasper">
> > > > > +               <level value="INFO" />
> > > > > +       </logger>
> > > > > +       <logger name="org.apache.tomcat">
> > > > > +               <level value="INFO" />
> > > > > +       </logger>
> > > > > +       <logger name="org.apache.tomcat.util.net">
> > > > > +               <level value="WARN" />
> > > > > +       </logger>
> > > > > +       <logger name="org.apache.coyote.http11">
> > > > > +               <level value="INFO" />
> > > > > +       </logger>
> > > > > +       <!-- Spring -->
> > > > > +       <logger name="org.springframework">
> > > > > +               <level value="INFO" />
> > > > > +       </logger>
> > > > > +       <logger name="org.springframework.beans.factory">
> > > > > +               <level value="INFO" />
> > > > > +       </logger>
> > > > > +       <logger name="org.springframework.beans.factory.xml">
> > > > > +               <level value="WARN" />
> > > > > +       </logger>
> > > > > +       <logger name="org.springframework.ui.context.support">
> > > > > +               <level value="WARN" />
> > > > > +       </logger>
> > > > > +       <logger name="org.springframework.web.context">
> > > > > +               <level value="INFO" />
> > > > > +       </logger>
> > > > > +       <logger name="org.springframework.web.context.support">
> > > > > +               <level value="WARN" />
> > > > > +       </logger>
> > > > > +       <logger name="org.quartz">
> > > > > +               <level value="WARN" />
> > > > > +       </logger>
> > > > > +       <!-- Caching -->
> > > > > +       <logger name="net.sf.ehcache">
> > > > > +               <level value="INFO" />
> > > > > +       </logger>
> > > > > +       <logger name="ch.qos">
> > > > > +               <level value="WARN" />
> > > > > +       </logger>
> > > > > +</configuration>
> > > > >
> > > > > Modified: incubator/openmeetings/trunk/singlewebapp/build.xml
> > > > > URL:
> > > > >
> > > >
> > >
> >
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/build.xml?rev=1306748&r1=1306747&r2=1306748&view=diff
> > > > >
> > > > >
> > > >
> > >
> >
> ==============================================================================
> > > > > --- incubator/openmeetings/trunk/singlewebapp/build.xml (original)
> > > > > +++ incubator/openmeetings/trunk/singlewebapp/build.xml Thu Mar 29
> > > > > 08:14:45 2012
> > > > > @@ -35,7 +35,7 @@
> > > > >        <property name="mainlibs.lib.dir"
> > > > > value="${project.lib.dir}/mainlibs" />
> > > > >        <property name="om.lib.dir" value="${project.lib.dir}/om" />
> > > > >        <property name="anakia.lib.dir"
> > > value="${project.lib.dir}/anakia"
> > > > />
> > > > > -       <property name="red5-screenshare.images"
> > > > > value="${basedir}/WebContent/red5-screenshare" />
> > > > > +       <property name="red5-screenshare.resources"
> > > > > value="${basedir}/WebContent/red5-screenshare" />
> > > > >        <property name="junit.lib.dir"
> > value="${project.lib.dir}/junit"
> > > />
> > > > >        <property name="rat.lib.dir" value="${project.lib.dir}/rat"
> />
> > > > >        <property name="dtd-generator.lib.dir"
> > > > > value="${project.lib.dir}/dtd-generator" />
> > > > > @@ -294,7 +294,7 @@
> > > > >                        <fileset dir="${main.out.dir}">
> > > > >                                <include name="org/red5/screen/**"
> />
> > > > >                        </fileset>
> > > > > -                       <fileset
> > file="${red5.lib}/conf/logback.xml"/>
> > > > > +                       <fileset
> > > > > file="${red5-screenshare.resources}/logback.xml"/>
> > > > >                        <manifest>
> > > > >                                <attribute name="Built-By"
> > > > > value="OpenMeetings - http://openmeetings.googlecode.com" />
> > > > >                                <attribute name="Built-On"
> > > > > value="${build.TODAY}" />
> > > > > @@ -321,7 +321,7 @@
> > > > >                        </dname>
> > > > >                </genkey>
> > > > >                <copy todir="${screenshare.out.dir}"
> filtering="true">
> > > > > -                       <fileset dir="${red5-screenshare.images}"
> />
> > > > > +                       <fileset
> dir="${red5-screenshare.resources}"
> > > > > includes="*.jpg"/>
> > > > >                        <fileset dir="${red5.server.lib}"
> > > > > includes="commons-codec*.jar" />
> > > > >                        <fileset dir="${red5.server.lib}"
> > > > > includes="httpclient*.jar" />
> > > > >                        <fileset dir="${red5.server.lib}"
> > > > > includes="httpcore*.jar" />
> > > > >
> > > > > Modified:
> > > > >
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/installation/ImportInitvalues.java
> > > > > URL:
> > > > >
> > > >
> > >
> >
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/installation/ImportInitvalues.java?rev=1306748&r1=1306747&r2=1306748&view=diff
> > > > >
> > > > >
> > > >
> > >
> >
> ==============================================================================
> > > > > ---
> > > > >
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/installation/ImportInitvalues.java
> > > > > (original)
> > > > > +++
> > > > >
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/installation/ImportInitvalues.java
> > > > > Thu Mar 29 08:14:45 2012
> > > > > @@ -479,8 +479,9 @@ public class ImportInitvalues {
> > > > >                cfgManagement.addConfByKey(3, "show.facebook.login",
> > ""
> > > +
> > > > > 0, null,
> > > > >                                "Show Facebook Login");
> > > > >
> > > > > -               cfgManagement.addConfByKey(3,
> > > > > "default.quality.screensharing", "0",
> > > > > -                               null, "Default selection in
> > > ScreenSharing
> > > > > Quality");
> > > > > +               cfgManagement.addConfByKey(3,
> > > > > "default.quality.screensharing", "1",
> > > > > +                                               null,
> > > > > +                                               "Default selection
> in
> > > > > ScreenSharing Quality:\n 0 - bigger frame rate, no resize\n 1 - no
> > > > resize\n
> > > > > 2 - size == 1/2 of selected area\n 3 - size == 3/8 of selected
> > area");
> > > > >
> > > > >                cfgManagement.addConfByKey(3,
> "default.dashboard.tab",
> > > > "0",
> > > > > null,
> > > > >                                "Default selection in Dashboard tabs
> > as
> > > > > tab-index-id");
> > > > >
> > > > > Modified:
> > > > >
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/CommonScreenShare.java
> > > > > URL:
> > > > >
> > > >
> > >
> >
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/CommonScreenShare.java?rev=1306748&r1=1306747&r2=1306748&view=diff
> > > > >
> > > > >
> > > >
> > >
> >
> ==============================================================================
> > > > > ---
> > > > >
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/CommonScreenShare.java
> > > > > (original)
> > > > > +++
> > > > >
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/CommonScreenShare.java
> > > > > Thu Mar 29 08:14:45 2012
> > > > > @@ -1,13 +1,11 @@
> > > > >  package org.red5.screen.webstart;
> > > > >
> > > > >  import java.awt.Color;
> > > > > -import java.awt.Graphics2D;
> > > > >  import java.awt.Image;
> > > > >  import java.awt.MouseInfo;
> > > > >  import java.awt.Point;
> > > > >  import java.awt.PointerInfo;
> > > > >  import java.awt.Rectangle;
> > > > > -import java.awt.RenderingHints;
> > > > >  import java.awt.Robot;
> > > > >  import java.awt.Toolkit;
> > > > >  import java.awt.datatransfer.Clipboard;
> > > > > @@ -22,14 +20,10 @@ import java.awt.event.KeyEvent;
> > > > >  import java.awt.event.WindowAdapter;
> > > > >  import java.awt.event.WindowEvent;
> > > > >  import java.awt.image.BufferedImage;
> > > > > -import java.awt.image.DataBuffer;
> > > > > -import java.io.ByteArrayOutputStream;
> > > > >  import java.io.IOException;
> > > > > -import java.io.OutputStream;
> > > > >  import java.util.HashMap;
> > > > >  import java.util.Iterator;
> > > > >  import java.util.Map;
> > > > > -import java.util.zip.DeflaterOutputStream;
> > > > >
> > > > >  import javax.imageio.ImageIO;
> > > > >  import javax.swing.ImageIcon;
> > > > > @@ -45,6 +39,7 @@ import org.red5.io.ITagWriter;
> > > > >  import org.red5.io.utils.ObjectMap;
> > > > >  import org.red5.screen.webstart.gui.VirtualScreen;
> > > > >  import org.red5.screen.webstart.gui.VirtualScreenBean;
> > > > > +import
> org.red5.screen.webstart.gui.VirtualScreenBean.ScreenQuality;
> > > > >  import org.red5.server.api.event.IEvent;
> > > > >  import org.red5.server.api.service.IPendingServiceCall;
> > > > >  import org.red5.server.net.rtmp.Channel;
> > > > > @@ -117,7 +112,7 @@ public class CommonScreenShare {
> > > > >        public String host = "btg199251";
> > > > >        public String app = "oflaDemo";
> > > > >        public int port = 1935;
> > > > > -       public int defaultQualityScreensharing = 0;
> > > > > +       public int defaultQualityScreensharing = 1;
> > > > >
> > > > >        public Long organization_id = 0L;
> > > > >        public Long user_id = null;
> > > > > @@ -157,11 +152,7 @@ public class CommonScreenShare {
> > > > >        public String label1092 = "Medium Quality -";
> > > > >        public String label1093 = "Low Quality -";
> > > > >
> > > > > -       public Float imgQuality = new Float(0.40);
> > > > > -
> > > > > -       // public Float scaleFactor = 1F;
> > > > > -       public float Ampl_factor = 1.3f;
> > > > > -
> > > > > +       public float Ampl_factor = 1f;
> > > > >        public boolean isConnected = false;
> > > > >
> > > > >        public Map<Integer, Boolean> currentPressedKeys = new
> > > > > HashMap<Integer, Boolean>();
> > > > > @@ -179,6 +170,9 @@ public class CommonScreenShare {
> > > > >        public void main(String[] args) {
> > > > >                try {
> > > > >                        if (args.length == 9) {
> > > > > +                               for (String arg : args) {
> > > > > +                                       logger.debug("arg: " +
> arg);
> > > > > +                               }
> > > > >
> > > > >                                host = args[0];
> > > > >                                app = args[1];
> > > > > @@ -308,13 +302,6 @@ public class CommonScreenShare {
> > > > >                        // *****
> > > > >                        // Text Recording
> > > > >                        textAreaHeaderRecording = new JLabel();
> > > > > -
> > > > > -                       // FIXME: Set Font to bold
> > > > > -                       // textAreaHeaderRecording.setB
> > > > > -                       // Font f =
> > textAreaHeaderRecording.getFont();
> > > > > -                       //
> > > > > textAreaHeaderRecording.setFont(f.deriveFont(f.getStyle() ^
> > > > > -                       // Font.BOLD));
> > > > > -
> > > > >
> >  textAreaHeaderRecording.setText(this.label869);
> > > > >                        contentPane.add(textAreaHeaderRecording);
> > > > >                        textAreaHeaderRecording.setBounds(10, 340,
> > 480,
> > > > 24);
> > > > > @@ -421,9 +408,6 @@ public class CommonScreenShare {
> > > > >                        PointerInfo a = MouseInfo.getPointerInfo();
> > > > >                        Point mouseP = a.getLocation();
> > > > >
> > > > > -                       // Integer x =
> > > > > Long.valueOf(Math.round(mouseP.getX())).intValue();
> > > > > -                       // Integer y =
> > > > > Long.valueOf(Math.round(mouseP.getY())).intValue();
> > > > > -
> > > > >                        Float scaleFactor =
> > > > > Float.valueOf(VirtualScreenBean.vScreenResizeX)
> > > > >                                        /
> > > > > Float.valueOf(VirtualScreenBean.vScreenSpinnerWidth);
> > > > >
> > > > > @@ -643,18 +627,6 @@ public class CommonScreenShare {
> > > > >
> > > > >                                // VirtualScreenBean
> > > > >
> > > > > -                               // Integer x = Math.round ( ( (
> > > > > -                               //
> > > > > Float.valueOf(returnMap.get("x").toString()).floatValue()
> > > > > -                               //
> *VirtualScreenBean.vScreenResizeX
> > > > > -                               //
> > > > > )/VirtualScreenBean.vScreenSpinnerWidth) / Ampl_factor) ;
> > > > > -                               // Integer y = Math.round ( ( (
> > > > > -                               //
> > > > > Float.valueOf(returnMap.get("y").toString()).floatValue()
> > > > > -                               //
> *VirtualScreenBean.vScreenResizeY
> > > > > -                               //
> > > > > )/VirtualScreenBean.vScreenSpinnerHeight)/ Ampl_factor) ;
> > > > > -                               //
> > > > > -
> > > > > -                               // logger.debug("x 1
> > > > "+returnMap.get("x"));
> > > > > -
> > > > >                                Float scaleFactor = Float
> > > > >
> > > > >  .valueOf(VirtualScreenBean.vScreenSpinnerWidth)
> > > > >                                                /
> > > > > Float.valueOf(VirtualScreenBean.vScreenResizeX);
> > > > > @@ -951,13 +923,10 @@ public class CommonScreenShare {
> > > > >                        ex.printStackTrace();
> > > > >                }
> > > > >                return "";
> > > > > -               // clippy.setContents( clippysContent ,null);
> > > > > //zur�cksetzen vom alten
> > > > > -               // Kontext
> > > > >        }
> > > > >
> > > > >        private void pressSpecialSign(String charValue, Robot
> > instance)
> > > {
> > > > >                Clipboard clippy =
> > > > > Toolkit.getDefaultToolkit().getSystemClipboard();
> > > > > -               // Transferable clippysContent =
> clippy.getContents(
> > > null
> > > > > );
> > > > >                try {
> > > > >
> > > > >                        Transferable transferableText = new
> > > > > StringSelection(charValue);
> > > > > @@ -1042,7 +1011,7 @@ public class CommonScreenShare {
> > > > >                                        logger.debug("The Stream was
> > > > > already started ");
> > > > >                                }
> > > > >
> > > > > -                               if (returnMap.get("modus") !=
> null) {
> > > > > +                               if (returnMap != null &&
> > > > > returnMap.get("modus") != null) {
> > > > >                                        if
> > > > > (returnMap.get("modus").toString()
> > > > >
> > > > >  .equals("startStreaming")) {
> > > > >
> > > > >  this.startButton.setEnabled(false);
> > > > > @@ -1076,12 +1045,7 @@ public class CommonScreenShare {
> > > > >                                logger.debug("setup capture thread
> > > > > vScreenSpinnerHeight "
> > > > >                                                +
> > > > > VirtualScreenBean.vScreenSpinnerHeight);
> > > > >
> > > > > -                               capture = new
> > > > > CaptureScreen(VirtualScreenBean.vScreenSpinnerX,
> > > > > -
> > > > > VirtualScreenBean.vScreenSpinnerY,
> > > > > -
> > > > > VirtualScreenBean.vScreenSpinnerWidth,
> > > > > -
> > > > > VirtualScreenBean.vScreenSpinnerHeight,
> > > > > -
> > > > > VirtualScreenBean.vScreenResizeX,
> > > > > -
> > > > > VirtualScreenBean.vScreenResizeY);
> > > > > +                               capture = new CaptureScreen();
> > > > >
> > > > >                                if (thread == null) {
> > > > >                                        thread = new
> Thread(capture);
> > > > > @@ -1154,11 +1118,6 @@ public class CommonScreenShare {
> > > > >
> > > > >                kt++;
> > > > >
> > > > > -               // if ( kt < 10 ) {
> > > > > -               // logger.debug( "+++ " + videoData );
> > > > > -               // System.out.println( "+++ " + videoData);
> > > > > -               // }
> > > > > -
> > > > >                RTMPMessage rtmpMsg = RTMPMessage.build(videoData);
> > > > >                instance.publishStreamData(publishStreamId,
> rtmpMsg);
> > > > >        }
> > > > > @@ -1170,14 +1129,6 @@ public class CommonScreenShare {
> > > > >        //
> > > > >
> > >
> ------------------------------------------------------------------------
> > > > >
> > > > >        private final class CaptureScreen extends Object implements
> > > > > Runnable {
> > > > > -               private volatile int x = 0;
> > > > > -               private volatile int y = 0;
> > > > > -               private volatile int resizeX;
> > > > > -               private volatile int resizeY;
> > > > > -
> > > > > -               private volatile int width = resizeX; // 320
> > > > > -               private volatile int height = resizeY; // 240
> > > > > -
> > > > >                private int timeBetweenFrames = 1000; // frameRate
> > > > >
> > > > >                private volatile long timestamp = 0;
> > > > > @@ -1185,7 +1136,7 @@ public class CommonScreenShare {
> > > > >                private volatile boolean active = true;
> > > > >                @SuppressWarnings("unused")
> > > > >                private volatile boolean stopped = false;
> > > > > -               private byte[] previousItems = null;
> > > > > +               private IScreenEncoder se;
> > > > >
> > > > >                //
> > > > >
> > >
> ------------------------------------------------------------------------
> > > > >                //
> > > > > @@ -1193,27 +1144,9 @@ public class CommonScreenShare {
> > > > >                //
> > > > >                //
> > > > >
> > >
> ------------------------------------------------------------------------
> > > > >
> > > > > -               public CaptureScreen(final int x, final int y,
> final
> > > int
> > > > > width,
> > > > > -                               final int height, int resizeX, int
> > > > > resizeY) {
> > > > > -
> > > > > -                       this.x = x;
> > > > > -                       this.y = y;
> > > > > -                       this.width = width;
> > > > > -                       this.height = height;
> > > > > -                       this.resizeX = resizeX;
> > > > > -                       this.resizeY = resizeY;
> > > > > -
> > > > > -                       if (VirtualScreenBean.vScreenScaleFactor
> > > > > -                                       .equals(label1090)) {
> > > > > -                               timeBetweenFrames = 100;
> > > > > -                       } else {
> > > > > -                               timeBetweenFrames = 1000;
> > > > > -                       }
> > > > > -
> > > > > -                       logger.debug("CaptureScreen: x=" + x + ",
> y="
> > > + y
> > > > > + ", w=" + width
> > > > > -                                       + ", h=" + height +
> > > ",resizeX=" +
> > > > > resizeX + " resizeY= "
> > > > > -                                       + resizeY);
> > > > > -
> > > > > +               public CaptureScreen() {
> > > > > +                       timeBetweenFrames =
> > > > > (VirtualScreenBean.screenQuality == ScreenQuality.VeryHigh) ? 100 :
> > > 1000;
> > > > > +                       se = new ScreenV1Encoder();
> > > > >                }
> > > > >
> > > > >                //
> > > > >
> > >
> ------------------------------------------------------------------------
> > > > > @@ -1234,7 +1167,7 @@ public class CommonScreenShare {
> > > > >                }
> > > > >
> > > > >                public void resetBuffer() {
> > > > > -                       this.previousItems = null;
> > > > > +                       se.reset();
> > > > >                }
> > > > >
> > > > >                //
> > > > >
> > >
> ------------------------------------------------------------------------
> > > > > @@ -1242,89 +1175,27 @@ public class CommonScreenShare {
> > > > >                // Thread loop
> > > > >                //
> > > > >                //
> > > > >
> > >
> ------------------------------------------------------------------------
> > > > > -
> > > > >                public void run() {
> > > > > -                       final int blockWidth = 32;
> > > > > -                       final int blockHeight = 32;
> > > > > -
> > > > > -                       int frameCounter = 0;
> > > > > -
> > > > > -                       int orig_width = width;
> > > > > -                       int orig_height = height;
> > > > > -
> > > > >                        try {
> > > > >                                Robot robot = new Robot();
> > > > >
> > > > > -                               this.previousItems = null;
> > > > > -
> > > > >                                while (active) {
> > > > >                                        final long ctime =
> > > > > System.currentTimeMillis();
> > > > >
> > > > > -                                       width = orig_width;
> > > > > -                                       height = orig_height;
> > > > > -
> > > > > -                                       BufferedImage image = robot
> > > > > -
> > > > > .createScreenCapture(new Rectangle(x, y, width,
> > > > > -
> > > > > height));
> > > > > -
> > > > > -                                       int width_new = resizeX;
> > > > > -                                       int height_new = resizeY;
> > > > > -                                       width = resizeX;
> > > > > -                                       height = resizeY;
> > > > > -                                       // Resize to 640*480
> > > > > -                                       // Create new (blank) image
> > of
> > > > > required (scaled) size
> > > > > -                                       BufferedImage image_raw =
> new
> > > > > BufferedImage(width_new,
> > > > > -                                                       height_new,
> > > > > BufferedImage.TYPE_INT_RGB);
> > > > > -
> > > > > -                                       Graphics2D graphics2D =
> > > > > image_raw.createGraphics();
> > > > > -
> graphics2D.setRenderingHint(
> > > > > -
> > > > > RenderingHints.KEY_INTERPOLATION,
> > > > > -
> > > > > RenderingHints.VALUE_INTERPOLATION_BICUBIC);
> > > > > -                                       graphics2D.drawImage(image,
> > 0,
> > > 0,
> > > > > width_new, height_new,
> > > > > -                                                       null);
> > > > > -                                       graphics2D.dispose();
> > > > > -
> > > > > -                                       // End resize
> > > > > -
> > > > > -                                       int scaledWidth = width;
> > > > > -                                       int scaledHeight = height;
> > > > > -
> > > > > -                                       byte[] current =
> > > > toBGR(image_raw);
> > > > > -                                       // if (scaleFactor != 1F) {
> > > > > -                                       //
> > > > > -                                       // logger.debug("Calc new
> > > Scaled
> > > > > Instance ",scaleFactor);
> > > > > -                                       //
> > > > > -                                       // scaledWidth =
> > > > > -                                       //
> > > > > Float.valueOf(Math.round(width*scaleFactor)).intValue();
> > > > > -                                       // scaledHeight =
> > > > > -                                       //
> > > > > Float.valueOf(Math.round(height*scaleFactor)).intValue();
> > > > > -                                       //
> > > > > -                                       // Image img =
> > > > > image_raw.getScaledInstance(scaledWidth,
> > > > > -                                       //
> > > > > scaledHeight,Image.SCALE_SMOOTH);
> > > > > -                                       //
> > > > > -                                       // BufferedImage
> > image_scaled =
> > > > new
> > > > > -                                       //
> BufferedImage(scaledWidth,
> > > > > -                                       //
> > > > > scaledHeight,BufferedImage.TYPE_3BYTE_BGR);
> > > > > -                                       //
> > > > > -                                       // Graphics2D biContext =
> > > > > image_scaled.createGraphics();
> > > > > -                                       // biContext.drawImage(img,
> > 0,
> > > 0,
> > > > > null);
> > > > > -                                       // current =
> > > toBGR(image_scaled);
> > > > > -                                       // } else {
> > > > > -                                       // current =
> > toBGR(image_raw);
> > > > > -                                       // }
> > > > > +                                       Rectangle screen = new
> > > > > Rectangle(VirtualScreenBean.vScreenSpinnerX,
> > > > > +
> > > > > VirtualScreenBean.vScreenSpinnerY,
> > > > > +
> > > > > VirtualScreenBean.vScreenSpinnerWidth,
> > > > > +
> > > > > VirtualScreenBean.vScreenSpinnerHeight);
> > > > > +
> > > > > +                                       BufferedImage image =
> > > > > robot.createScreenCapture(screen);
> > > > >
> > > > >                                        try {
> > > > > -                                               // timestamp +=
> > > (1000000
> > > > /
> > > > > timeBetweenFrames);
> > > > >                                                timestamp +=
> > > > > timeBetweenFrames;
> > > > >
> > > > > -                                               final byte[]
> > > screenBytes
> > > > =
> > > > > encode(current,
> > > > > -
> > > > > this.previousItems, blockWidth, blockHeight,
> > > > > -
> > > > > scaledWidth, scaledHeight);
> > > > > -
> > > > > pushVideo(screenBytes.length, screenBytes, timestamp);
> > > > > -                                               this.previousItems
> =
> > > > > current;
> > > > > +                                               byte[] data =
> > > > > se.encode(screen, image, new
> > > Rectangle(VirtualScreenBean.vScreenResizeX,
> > > > > +
> > > > > VirtualScreenBean.vScreenResizeY));
> > > > >
> > > > > -                                               if (++frameCounter
> %
> > > 100
> > > > > == 0)
> > > > > -
> > > > this.previousItems
> > > > > = null;
> > > > > +
> > pushVideo(data.length,
> > > > > data, timestamp);
> > > > >                                        } catch (Exception e) {
> > > > >                                                e.printStackTrace();
> > > > >                                        }
> > > > > @@ -1339,132 +1210,5 @@ public class CommonScreenShare {
> > > > >                                e.printStackTrace();
> > > > >                        }
> > > > >                }
> > > > > -
> > > > > -               //
> > > > >
> > >
> ------------------------------------------------------------------------
> > > > > -               //
> > > > > -               // Private
> > > > > -               //
> > > > > -               //
> > > > >
> > >
> ------------------------------------------------------------------------
> > > > > -
> > > > > -               private byte[] toBGR(BufferedImage image) {
> > > > > -                       final int width = image.getWidth();
> > > > > -                       final int height = image.getHeight();
> > > > > -
> > > > > -                       byte[] buf = new byte[3 * width * height];
> > > > > -
> > > > > -                       final DataBuffer buffer =
> > > > > image.getData().getDataBuffer();
> > > > > -
> > > > > -                       for (int y = 0; y < height; y++) {
> > > > > -                               for (int x = 0; x < width; x++) {
> > > > > -                                       final int rgb =
> > > buffer.getElem(y
> > > > *
> > > > > width + x);
> > > > > -                                       final int offset = 3 * (y *
> > > width
> > > > > + x);
> > > > > -
> > > > > -                                       buf[offset + 0] = (byte)
> > (rgb &
> > > > > 0xFF);
> > > > > -                                       buf[offset + 1] = (byte)
> > ((rgb
> > > >>
> > > > > 8) & 0xFF);
> > > > > -                                       buf[offset + 2] = (byte)
> > ((rgb
> > > >>
> > > > > 16) & 0xFF);
> > > > > -                               }
> > > > > -                       }
> > > > > -
> > > > > -                       return buf;
> > > > > -               }
> > > > > -
> > > > > -               private byte[] encode(final byte[] current, final
> > > byte[]
> > > > > previous,
> > > > > -                               final int blockWidth, final int
> > > > > blockHeight, final int width,
> > > > > -                               final int height) throws Exception
> {
> > > > > -                       ByteArrayOutputStream baos = new
> > > > > ByteArrayOutputStream(16 * 1024);
> > > > > -
> > > > > -                       if (previous == null) {
> > > > > -                               baos.write(getTag(0x01, 0x03)); //
> > > > > keyframe (all cells)
> > > > > -                       } else {
> > > > > -                               baos.write(getTag(0x02, 0x03)); //
> > > frame
> > > > > (changed cells)
> > > > > -                       }
> > > > > -
> > > > > -                       // write header
> > > > > -                       final int wh = width + ((blockWidth / 16 -
> 1)
> > > <<
> > > > > 12);
> > > > > -                       final int hh = height + ((blockHeight / 16
> -
> > 1)
> > > > <<
> > > > > 12);
> > > > > -
> > > > > -                       writeShort(baos, wh);
> > > > > -                       writeShort(baos, hh);
> > > > > -
> > > > > -                       // write content
> > > > > -                       int y0 = height;
> > > > > -                       int x0 = 0;
> > > > > -                       int bwidth = blockWidth;
> > > > > -                       int bheight = blockHeight;
> > > > > -
> > > > > -                       while (y0 > 0) {
> > > > > -                               bheight = Math.min(y0,
> blockHeight);
> > > > > -                               y0 -= bheight;
> > > > > -
> > > > > -                               bwidth = blockWidth;
> > > > > -                               x0 = 0;
> > > > > -
> > > > > -                               while (x0 < width) {
> > > > > -                                       bwidth = (x0 + blockWidth >
> > > > width)
> > > > > ? width - x0
> > > > > -                                                       :
> blockWidth;
> > > > > -
> > > > > -                                       final boolean changed =
> > > > > isChanged(current, previous, x0,
> > > > > -                                                       y0, bwidth,
> > > > > bheight, width, height);
> > > > > -
> > > > > -                                       if (changed) {
> > > > > -
> ByteArrayOutputStream
> > > > > blaos = new ByteArrayOutputStream(
> > > > > -                                                               4 *
> > > > 1024);
> > > > > -
> > > > > -
> DeflaterOutputStream
> > > dos
> > > > =
> > > > > new DeflaterOutputStream(
> > > > > -
> > blaos);
> > > > > -
> > > > > -                                               for (int y = 0; y <
> > > > > bheight; y++) {
> > > > > -
> > > > dos.write(current,
> > > > > 3 * ((y0 + bheight - y - 1)
> > > > > -
> > >   *
> > > > > width + x0), 3 * bwidth);
> > > > > -                                               }
> > > > > -
> > > > > -                                               dos.finish();
> > > > > -
> > > > > -                                               final byte[] bbuf =
> > > > > blaos.toByteArray();
> > > > > -                                               final int written =
> > > > > bbuf.length;
> > > > > -
> > > > > -                                               // write DataSize
> > > > > -                                               writeShort(baos,
> > > > written);
> > > > > -                                               // write Data
> > > > > -                                               baos.write(bbuf, 0,
> > > > > written);
> > > > > -                                       } else {
> > > > > -                                               // write DataSize
> > > > > -                                               writeShort(baos,
> 0);
> > > > > -                                       }
> > > > > -
> > > > > -                                       x0 += bwidth;
> > > > > -                               }
> > > > > -                       }
> > > > > -
> > > > > -                       return baos.toByteArray();
> > > > > -               }
> > > > > -
> > > > > -               private void writeShort(OutputStream os, final int
> n)
> > > > > throws Exception {
> > > > > -                       os.write((n >> 8) & 0xFF);
> > > > > -                       os.write((n >> 0) & 0xFF);
> > > > > -               }
> > > > > -
> > > > > -               public boolean isChanged(final byte[] current,
> final
> > > > > byte[] previous,
> > > > > -                               final int x0, final int y0, final
> int
> > > > > blockWidth,
> > > > > -                               final int blockHeight, final int
> > width,
> > > > > final int height) {
> > > > > -                       if (previous == null)
> > > > > -                               return true;
> > > > > -
> > > > > -                       for (int y = y0, ny = y0 + blockHeight; y <
> > ny;
> > > > > y++) {
> > > > > -                               final int foff = 3 * (x0 + width *
> > y);
> > > > > -                               final int poff = 3 * (x0 + width *
> > y);
> > > > > -
> > > > > -                               for (int i = 0, ni = 3 *
> blockWidth;
> > i
> > > <
> > > > > ni; i++) {
> > > > > -                                       if (current[foff + i] !=
> > > > > previous[poff + i])
> > > > > -                                               return true;
> > > > > -                               }
> > > > > -                       }
> > > > > -
> > > > > -                       return false;
> > > > > -               }
> > > > > -
> > > > > -               public int getTag(final int frame, final int
> codec) {
> > > > > -                       return ((frame & 0x0F) << 4) + ((codec &
> > 0x0F)
> > > <<
> > > > > 0);
> > > > > -               }
> > > > >        }
> > > > >  }
> > > > >
> > > > > Added:
> > > > >
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/IScreenEncoder.java
> > > > > URL:
> > > > >
> > > >
> > >
> >
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/IScreenEncoder.java?rev=1306748&view=auto
> > > > >
> > > > >
> > > >
> > >
> >
> ==============================================================================
> > > > > ---
> > > > >
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/IScreenEncoder.java
> > > > > (added)
> > > > > +++
> > > > >
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/IScreenEncoder.java
> > > > > Thu Mar 29 08:14:45 2012
> > > > > @@ -0,0 +1,30 @@
> > > > > +/*
> > > > > + * Licensed to the Apache Software Foundation (ASF) under one
> > > > > + * or more contributor license agreements.  See the NOTICE file
> > > > > + * distributed with this work for additional information
> > > > > + * regarding copyright ownership.  The ASF licenses this file
> > > > > + * to you under the Apache License, Version 2.0 (the
> > > > > + * "License") +  you may not use this file except in compliance
> > > > > + * with the License.  You may obtain a copy of the License at
> > > > > + *
> > > > > + *   http://www.apache.org/licenses/LICENSE-2.0
> > > > > + *
> > > > > + * Unless required by applicable law or agreed to in writing,
> > > > > + * software distributed under the License is distributed on an
> > > > > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > > > > + * KIND, either express or implied.  See the License for the
> > > > > + * specific language governing permissions and limitations
> > > > > + * under the License.
> > > > > + */
> > > > > +package org.red5.screen.webstart;
> > > > > +
> > > > > +import java.awt.Rectangle;
> > > > > +import java.awt.image.BufferedImage;
> > > > > +import java.io.IOException;
> > > > > +
> > > > > +public interface IScreenEncoder {
> > > > > +
> > > > > +       byte[] encode(Rectangle screen, BufferedImage img,
> Rectangle
> > > > size)
> > > > >  throws IOException;
> > > > > +
> > > > > +       void reset();
> > > > > +}
> > > > >
> > > > > Added:
> > > > >
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/ScreenV1Encoder.java
> > > > > URL:
> > > > >
> > > >
> > >
> >
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/ScreenV1Encoder.java?rev=1306748&view=auto
> > > > >
> > > > >
> > > >
> > >
> >
> ==============================================================================
> > > > > ---
> > > > >
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/ScreenV1Encoder.java
> > > > > (added)
> > > > > +++
> > > > >
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/ScreenV1Encoder.java
> > > > > Thu Mar 29 08:14:45 2012
> > > > > @@ -0,0 +1,146 @@
> > > > > +/*
> > > > > + * Licensed to the Apache Software Foundation (ASF) under one
> > > > > + * or more contributor license agreements.  See the NOTICE file
> > > > > + * distributed with this work for additional information
> > > > > + * regarding copyright ownership.  The ASF licenses this file
> > > > > + * to you under the Apache License, Version 2.0 (the
> > > > > + * "License") +  you may not use this file except in compliance
> > > > > + * with the License.  You may obtain a copy of the License at
> > > > > + *
> > > > > + *   http://www.apache.org/licenses/LICENSE-2.0
> > > > > + *
> > > > > + * Unless required by applicable law or agreed to in writing,
> > > > > + * software distributed under the License is distributed on an
> > > > > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > > > > + * KIND, either express or implied.  See the License for the
> > > > > + * specific language governing permissions and limitations
> > > > > + * under the License.
> > > > > + */
> > > > > +package org.red5.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;
> > > > > +
> > > > > +public class ScreenV1Encoder implements IScreenEncoder {
> > > > > +       private BufferedImage last = null;
> > > > > +       private static int KEY_FRAME_INDEX = 100;
> > > > > +       private static int DEFAULT_BLOCK_SIZE = 32;
> > > > > +       private int keyFrameIndex;
> > > > > +       private int frameCount = 0;
> > > > > +       private int blockSize;
> > > > > +       private Rectangle screen;
> > > > > +
> > > > > +       public ScreenV1Encoder() {
> > > > > +               this(KEY_FRAME_INDEX, DEFAULT_BLOCK_SIZE);
> > > > > +       }
> > > > > +
> > > > > +       //will create square blocks
> > > > > +       public ScreenV1Encoder(int keyFrameIndex, int blockSize) {
> > > > > +               this.keyFrameIndex = keyFrameIndex;
> > > > > +               if (blockSize < 16 || blockSize > 256 || blockSize
> %
> > 16
> > > > !=
> > > > > 0) {
> > > > > +                       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;
> > > > > +       }
> > > > > +
> > > > > +       public byte[] encode(Rectangle screen, BufferedImage _img,
> > > > > Rectangle size) throws IOException {
> > > > > +               BufferedImage img = resize(_img, size);
> > > > > +               Rectangle imgArea = new Rectangle(img.getWidth(),
> > > > > img.getHeight());
> > > > > +               Rectangle area = getNextBlock(imgArea, null);
> > > > > +               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));
> > > > > +               writeShort(ba, imgArea.height + ((blockSize / 16 -
> 1)
> > > <<
> > > > > 12));
> > > > > +
> > > > > +               while (area.width > 0 && area.height > 0) {
> > > > > +                       writeBytesIfChanged(ba, isKeyFrame, img,
> > area);
> > > > > +                       area = getNextBlock(imgArea, area);
> > > > > +               }
> > > > > +               this.screen = screen;
> > > > > +               last = img;
> > > > > +               return ba.toByteArray();
> > > > > +       }
> > > > > +
> > > > > +       public void reset() {
> > > > > +               last = null;
> > > > > +       }
> > > > > +
> > > > > +       private Rectangle getNextBlock(Rectangle img, Rectangle
> > _prev)
> > > {
> > > > > +               Rectangle prev;
> > > > > +               if (_prev == null) {
> > > > > +                       prev = new Rectangle(0, Math.max(0,
> > img.height
> > > -
> > > > > blockSize), blockSize, blockSize);
> > > > > +               } else {
> > > > > +                       prev = new Rectangle(_prev);
> > > > > +                       if (prev.x + prev.width == img.getWidth())
> {
> > > > > +                               if (prev.y == 0) return new
> > > Rectangle();
> > > > > //the end of the image
> > > > > +                               //next row
> > > > > +                               prev.x = 0; //reset position
> > > > > +                               prev.width = blockSize; //reset
> width
> > > > > +                               prev.y -= (prev.y > blockSize ?
> > > blockSize
> > > > > : prev.y);
> > > > > +                       } else {
> > > > > +                               prev.x += blockSize;
> > > > > +                       }
> > > > > +               }
> > > > > +               return img.intersection(prev);
> > > > > +       }
> > > > > +
> > > > > +       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);
> > > > > +               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
> > > > > +                               });
> > > > > +                       }
> > > > > +               }
> > > > > +               dos.finish();
> > > > > +               if (changed) {
> > > > > +                       final int written = baos.size();
> > > > > +                       writeShort(ba, written);
> > > > > +                       ba.write(baos.toByteArray(), 0, written);
> > > > > +               } else {
> > > > > +                       writeShort(ba, 0);
> > > > > +               }
> > > > > +       }
> > > > > +
> > > > > +       public int getTag(final int frame, final int codec) {
> > > > > +               return ((frame & 0x0F) << 4) + ((codec & 0x0F) <<
> 0);
> > > > > +       }
> > > > > +
> > > > > +       private void writeShort(OutputStream os, final int n)
> throws
> > > > > IOException {
> > > > > +               os.write((n >> 8) & 0xFF);
> > > > > +               os.write((n >> 0) & 0xFF);
> > > > > +       }
> > > > > +}
> > > > >
> > > > > Modified:
> > > > >
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreen.java
> > > > > URL:
> > > > >
> > > >
> > >
> >
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreen.java?rev=1306748&r1=1306747&r2=1306748&view=diff
> > > > >
> > > > >
> > > >
> > >
> >
> ==============================================================================
> > > > > ---
> > > > >
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreen.java
> > > > > (original)
> > > > > +++
> > > > >
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreen.java
> > > > > Thu Mar 29 08:14:45 2012
> > > > > @@ -18,27 +18,29 @@
> > > > >  */
> > > > >  package org.red5.screen.webstart.gui;
> > > > >
> > > > > -import javax.imageio.ImageIO;
> > > > >  import java.awt.Color;
> > > > >  import java.awt.Dimension;
> > > > >  import java.awt.Image;
> > > > >  import java.awt.Rectangle;
> > > > >  import java.awt.Robot;
> > > > > +import java.awt.event.ActionEvent;
> > > > > +import java.awt.event.ActionListener;
> > > > >  import java.awt.image.BufferedImage;
> > > > >
> > > > > -import javax.swing.SwingConstants;
> > > > > +import javax.imageio.ImageIO;
> > > > >  import javax.swing.ImageIcon;
> > > > > -import javax.swing.JLabel;
> > > > >  import javax.swing.JComboBox;
> > > > > +import javax.swing.JLabel;
> > > > >  import javax.swing.JSpinner;
> > > > >  import javax.swing.SpinnerNumberModel;
> > > > > +import javax.swing.SwingConstants;
> > > > >  import javax.swing.event.ChangeEvent;
> > > > >  import javax.swing.event.ChangeListener;
> > > > > -import java.awt.event.*;
> > > > >
> > > > >  import org.red5.screen.webstart.BlankArea;
> > > > >  import org.red5.screen.webstart.CommonScreenShare;
> > > > >  import org.red5.screen.webstart.ScreenShare;
> > > > > +import
> org.red5.screen.webstart.gui.VirtualScreenBean.ScreenQuality;
> > > > >  import org.slf4j.Logger;
> > > > >  import org.slf4j.LoggerFactory;
> > > > >
> > > > > @@ -50,6 +52,40 @@ public class VirtualScreen {
> > > > >
> > > > >        public boolean doUpdateBounds = true;
> > > > >
> > > > > +       private class KeyValue<T> {
> > > > > +               private String key;
> > > > > +               private T value;
> > > > > +
> > > > > +               public KeyValue(String key, T value) {
> > > > > +                       this.key = key;
> > > > > +                       this.value = value;
> > > > > +               }
> > > > > +
> > > > > +               @SuppressWarnings("unused")
> > > > > +               public String getKey() { return key; }
> > > > > +               public T getValue() { return value; }
> > > > > +
> > > > > +               @Override
> > > > > +               public String toString() { return key; }
> > > > > +
> > > > > +               @Override
> > > > > +               public boolean equals(Object obj) {
> > > > > +                       if (obj instanceof KeyValue) {
> > > > > +                               @SuppressWarnings("unchecked")
> > > > > +                               KeyValue<T> kv = (KeyValue<T>) obj;
> > > > > +                               return
> (kv.value.equals(this.value));
> > > > > +                       }
> > > > > +                       return false;
> > > > > +               }
> > > > > +
> > > > > +               @Override
> > > > > +               public int hashCode() {
> > > > > +                       int hash = 7;
> > > > > +                       hash = 97 * hash + (this.value != null ?
> > > > > this.value.hashCode() : 0);
> > > > > +                       return hash;
> > > > > +               }
> > > > > +       }
> > > > > +
> > > > >        public VirtualScreen(CommonScreenShare css) throws
> Exception {
> > > > >                this.css = css;
> > > > >
> > > > > @@ -175,7 +211,6 @@ public class VirtualScreen {
> > > > >                css.jVScreenXSpin.setBounds(400, 170, 60, 24);
> > > > >                css.jVScreenXSpin.addChangeListener( new
> > > ChangeListener(){
> > > > >                        public void stateChanged(ChangeEvent arg0) {
> > > > > -                               // TODO Auto-generated method stub
> > > > >                                calcNewValueXSpin();
> > > > >                        }
> > > > >                });
> > > > > @@ -194,7 +229,6 @@ public class VirtualScreen {
> > > > >                css.jVScreenYSpin.setBounds(400, 200, 60, 24);
> > > > >                css.jVScreenYSpin.addChangeListener( new
> > > ChangeListener(){
> > > > >                        public void stateChanged(ChangeEvent arg0) {
> > > > > -                               // TODO Auto-generated method stub
> > > > >                                calcNewValueYSpin();
> > > > >                        }
> > > > >                });
> > > > > @@ -213,7 +247,6 @@ public class VirtualScreen {
> > > > >                css.jVScreenWidthSpin.setBounds(400, 240, 60, 24);
> > > > >                css.jVScreenWidthSpin.addChangeListener( new
> > > > > ChangeListener(){
> > > > >                        public void stateChanged(ChangeEvent arg0) {
> > > > > -                               // TODO Auto-generated method stub
> > > > >                                calcNewValueWidthSpin();
> > > > >                        }
> > > > >                });
> > > > > @@ -232,15 +265,12 @@ public class VirtualScreen {
> > > > >                css.jVScreenHeightSpin.setBounds(400, 270, 60, 24);
> > > > >                css.jVScreenHeightSpin.addChangeListener( new
> > > > > ChangeListener(){
> > > > >                        public void stateChanged(ChangeEvent arg0) {
> > > > > -                               // TODO Auto-generated method stub
> > > > >                                calcNewValueHeightSpin();
> > > > >                        }
> > > > >                });
> > > > >                css.t.add(css.jVScreenHeightSpin);
> > > > >
> > > > >
> > > > > -               //String[] selectResize = { css.label1090,
> > > css.label1091,
> > > > > css.label1092, css.label1093 };
> > > > > -               String[] selectResize = { css.label1091,
> > css.label1092,
> > > > > css.label1093 };
> > > > >                VirtualScreenBean.vScreenResizeX = 640;
> > > > >                VirtualScreenBean.vScreenResizeY = 400;
> > > > >
> > > > > @@ -249,84 +279,55 @@ public class VirtualScreen {
> > > > >                css.vscreenResizeLabel.setBounds(250, 300, 200,24 );
> > > > >                css.t.add(css.vscreenResizeLabel);
> > > > >
> > > > > -               JComboBox comboResize  = new
> JComboBox(selectResize);
> > > > > +               JComboBox comboResize  = new JComboBox();
> > > > > +               comboResize.addItem(new
> > > > > KeyValue<ScreenQuality>(css.label1090, ScreenQuality.VeryHigh));
> > > > > +               comboResize.addItem(new
> > > > > KeyValue<ScreenQuality>(css.label1091, ScreenQuality.High));
> > > > > +               comboResize.addItem(new
> > > > > KeyValue<ScreenQuality>(css.label1092, ScreenQuality.Medium));
> > > > > +               comboResize.addItem(new
> > > > > KeyValue<ScreenQuality>(css.label1093, ScreenQuality.Low));
> > > > >                comboResize.setBounds(250, 330, 200, 24);
> > > > > -               comboResize.addActionListener(new
> GetResizeChoice());
> > > > > +               comboResize.addActionListener(new ActionListener(){
> > > > > +                       @SuppressWarnings("unchecked")
> > > > > +                       public void actionPerformed(ActionEvent e)
> {
> > > > > +                               JComboBox cb =
> > > (JComboBox)e.getSource();
> > > > > +                       VirtualScreenBean.screenQuality =
> > > > > ((KeyValue<ScreenQuality>)cb.getSelectedItem()).getValue();
> > > > > +                       calcRescaleFactors();
> > > > > +                       }
> > > > > +               });
> > > > >
> > > > >  comboResize.setSelectedIndex(css.defaultQualityScreensharing);
> > > > >
> > > > >                css.jVScreenResizeMode = comboResize;
> > > > >                css.t.add(css.jVScreenResizeMode);
> > > > >
> > > > >        }
> > > > > -       class GetResizeChoice implements ActionListener
> > > > > -       {
> > > > > -               public void actionPerformed (ActionEvent e)
> > > > > -               {
> > > > > -
> > > > > -                       JComboBox cb = (JComboBox)e.getSource();
> > > > > -               String petName = (String)cb.getSelectedItem();
> > > > > -
> > > > > -               VirtualScreenBean.vScreenScaleFactor = petName;
> > > > > -
> > > > > -               calcRescaleFactors();
> > > > > -
> > > > > -               }
> > > > > -       }
> > > > >
> > > > >        /**
> > > > >         * Needs to be always invoked after every re-scaling
> > > > >         */
> > > > >        void calcRescaleFactors() {
> > > > > -
> > > > >                logger.debug("calcRescaleFactors -- ");
> > > > > -
> > > > > if(VirtualScreenBean.vScreenScaleFactor.equals(css.label1090))
> > > > > -        {
> > > > > -                       logger.debug("resize:
> > > > >
> > > >
> > >
> >
> X:"+Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue()+
> > > > > -                                       "
> > > > >
> > > >
> > >
> >
> Y:"+Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue());
> > > > > -
> > > > > -                       VirtualScreenBean.vScreenResizeX =
> > > > >
> > >
> Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue();
> > > > > -                       VirtualScreenBean.vScreenResizeY =
> > > > >
> > >
> Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue();
> > > > > -                       updateVScreenBounds();
> > > > > -        }
> > > > > -               else
> > > > > if(VirtualScreenBean.vScreenScaleFactor.equals(css.label1091))
> > > > > -        {
> > > > > -               logger.debug("resize:
> > > > >
> > > >
> > >
> >
> X:"+Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue()+
> > > > > -                                                       "
> > > > >
> > > >
> > >
> >
> Y:"+Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue());
> > > > > -
> > > > > -               VirtualScreenBean.vScreenResizeX =
> > > > >
> > >
> Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue();
> > > > > -               VirtualScreenBean.vScreenResizeY =
> > > > >
> > >
> Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue();
> > > > > -               updateVScreenBounds();
> > > > > -        }
> > > > > -        else
> > > > > if(VirtualScreenBean.vScreenScaleFactor.equals(css.label1092))
> > > > > -        {
> > > > > -               logger.debug("resize:
> > > > >
> > > >
> > >
> >
> X:"+Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue()/2+
> > > > > -                                                       "
> > > > >
> > > >
> > >
> >
> Y:"+Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue()/2);
> > > > > -
> > > > > -               VirtualScreenBean.vScreenResizeX =
> > > > >
> > > >
> > >
> >
> (Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue())/2;
> > > > > -               VirtualScreenBean.vScreenResizeY =
> > > > >
> > > >
> > >
> >
> (Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue())/2;
> > > > > -               updateVScreenBounds();
> > > > > -        }
> > > > > -        else
> > > > > if(VirtualScreenBean.vScreenScaleFactor.equals(css.label1093))
> > > > > -        {
> > > > > -               logger.debug("resize:
> > > > >
> > > >
> > >
> >
> X:"+(Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue()/8)*3+
> > > > > -                                                       "
> > > > >
> > > >
> > >
> >
> Y:"+(Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue()/8)*3);
> > > > > -
> > > > > -               VirtualScreenBean.vScreenResizeX =
> > > > >
> > > >
> > >
> >
> (Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue()/8)*3;
> > > > > -               VirtualScreenBean.vScreenResizeY =
> > > > >
> > > >
> > >
> >
> (Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue()/8)*3;
> > > > > -               updateVScreenBounds();
> > > > > -        }
> > > > > -
> > > > > -                logger.debug("########## calcRescaleFactors
> > > > > vScreenResizeX " + VirtualScreenBean.vScreenResizeX);
> > > > > -         logger.debug("########## calcRescaleFactors
> vScreenResizeY
> > "
> > > +
> > > > > VirtualScreenBean.vScreenResizeY);
> > > > > -         logger.debug("########## calcRescaleFactors
> > > vScreenScaleFactor
> > > > "
> > > > > + VirtualScreenBean.vScreenScaleFactor);
> > > > > -
> > > > > +               VirtualScreenBean.vScreenResizeX =
> > > > >
> > >
> Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue();
> > > > > +               VirtualScreenBean.vScreenResizeY =
> > > > >
> > >
> Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue();
> > > > > +               switch (VirtualScreenBean.screenQuality) {
> > > > > +                       case VeryHigh:
> > > > > +                       case High:
> > > > > +                               break;
> > > > > +                       case Medium:
> > > > > +                               VirtualScreenBean.vScreenResizeX *=
> > > 1/2;
> > > > > +                               VirtualScreenBean.vScreenResizeY *=
> > 2;
> > > > > +                               break;
> > > > > +                       case Low:
> > > > > +                               VirtualScreenBean.vScreenResizeX *=
> > > 3/8;
> > > > > +                               VirtualScreenBean.vScreenResizeY *=
> > > 3/8;
> > > > > +                               break;
> > > > > +               }
> > > > > +               logger.debug("resize: X:" +
> > > > > VirtualScreenBean.vScreenResizeX + " Y: " +
> > > > > VirtualScreenBean.vScreenResizeY);
> > > > > +               updateVScreenBounds();
> > > > >        }
> > > > >
> > > > >        void calcNewValueXSpin(){
> > > > >                if (this.doUpdateBounds){
> > > > >                        int newX =
> > > > >
> Integer.valueOf(css.jVScreenXSpin.getValue().toString()).intValue();
> > > > >
>  if(VirtualScreenBean.vScreenSpinnerWidth+newX
> > >
> > > > > VirtualScreenBean.screenWidthMax){
> > > > > -//                             System.out.println("WARNING X
> > > > > "+VirtualScreenBean.vScreenSpinnerWidth+" "+newX);
> > > > >
> > > > >
> > > >
> > >
> >
>  newX=VirtualScreenBean.screenWidthMax-VirtualScreenBean.vScreenSpinnerWidth;
> > > > >                                css.jVScreenXSpin.setValue(newX);
> > > > >                                if (this.showWarning)
> > > > > css.showBandwidthWarning("Reduce the width of the SharingScreen
> > before
> > > > you
> > > > > try to move it left");
> > > > > @@ -363,7 +364,6 @@ public class VirtualScreen {
> > > > >                if (this.doUpdateBounds){
> > > > >                        int newWidth =
> > > > >
> > >
> Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue();
> > > > >
>  if(VirtualScreenBean.vScreenSpinnerX+newWidth
> > >
> > > > > VirtualScreenBean.screenWidthMax){
> > > > > -//                             System.out.println("WARNING
> WIDTH");
> > > > >
> > > > >
> > > >
> > >
> >
>  newWidth=VirtualScreenBean.screenWidthMax-VirtualScreenBean.vScreenSpinnerX;
> > > > >
> > >  css.jVScreenWidthSpin.setValue(newWidth);
> > > > >                                if
> > > > > (this.showWarning)css.showBandwidthWarning("Reduce the x of the
> > > > > SharingScreen before you try to make it wider");
> > > > >
> > > > > Modified:
> > > > >
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreenBean.java
> > > > > URL:
> > > > >
> > > >
> > >
> >
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreenBean.java?rev=1306748&r1=1306747&r2=1306748&view=diff
> > > > >
> > > > >
> > > >
> > >
> >
> ==============================================================================
> > > > > ---
> > > > >
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreenBean.java
> > > > > (original)
> > > > > +++
> > > > >
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreenBean.java
> > > > > Thu Mar 29 08:14:45 2012
> > > > > @@ -18,11 +18,8 @@
> > > > >  */
> > > > >  package org.red5.screen.webstart.gui;
> > > > >
> > > > > -import java.awt.Robot;
> > > > >
> > > > >  public class VirtualScreenBean {
> > > > > -
> > > > > -
> > > > >        /**
> > > > >         * image recalcing value's from the virtual Screen drawer
> > > > >         */
> > > > > @@ -47,13 +44,15 @@ public class VirtualScreenBean {
> > > > >        public static int vScreenSpinnerX = 0;
> > > > >        public static int vScreenSpinnerY = 0;
> > > > >
> > > > > -       public static String vScreenScaleFactor = "Medium Quality";
> > > > > +       public static ScreenQuality screenQuality =
> > > ScreenQuality.Medium;
> > > > >
> > > > >        public static int vScreenResizeX = 480;
> > > > >        public static int vScreenResizeY = 360;
> > > > >
> > > > > -
> > > > > -       public static Robot robot = null;
> > > > > -
> > > > > -       public static Float imgQuality = new Float(0.40);
> > > > > +       public enum ScreenQuality {
> > > > > +               VeryHigh
> > > > > +               , High
> > > > > +               , Medium
> > > > > +               , Low
> > > > > +       }
> > > > >  }
> > > > >
> > > > >
> > > > >
> > > >
> > > >
> > > > --
> > > > Sebastian Wagner
> > > > https://twitter.com/#!/dead_lock
> > > > http://www.openmeetings.de <
> http://incubator.apache.org/openmeetings/>
> > > > http://www.webbase-design.de
> > > > http://www.wagner-sebastian.com
> > > > seba.wagner@gmail.com
> > > >
> > >
> > >
> > >
> > > --
> > > WBR
> > > Maxim aka solomax
> > >
> >
> >
> >
> > --
> > Sebastian Wagner
> > https://twitter.com/#!/dead_lock
> > http://www.openmeetings.de <http://incubator.apache.org/openmeetings/>
> > http://www.webbase-design.de
> > http://www.wagner-sebastian.com
> > seba.wagner@gmail.com
> >
>
>
>
> --
> WBR
> Maxim aka solomax
>



-- 
Sebastian Wagner
https://twitter.com/#!/dead_lock
http://www.openmeetings.de <http://incubator.apache.org/openmeetings/>
http://www.webbase-design.de
http://www.wagner-sebastian.com
seba.wagner@gmail.com

Re: svn commit: r1306748 - in /incubator/openmeetings/trunk/singlewebapp: ./ WebContent/red5-screenshare/ src/org/openmeetings/app/installation/ src/org/red5/screen/webstart/ src/org/red5/screen/webstart/gui/

Posted by Maxim Solodovnik <so...@gmail.com>.
I mean "Screen Video bitstream format" section in
this swf_file_format_spec_v10.pdf document
its 2.5 pages not one, but its too general.


On Fri, Mar 30, 2012 at 14:08, seba.wagner@gmail.com
<se...@gmail.com>wrote:

> That would be nice, I have written the code 3-4 years ago so it would be
> nice if you find the time to refactor it.
>
> 1 page of documentation is too few? You mean the part about SHA1 in the
> RTMP spec ?
>
> 2012/3/30 Maxim Solodovnik <so...@gmail.com>
>
> > I was able to find _some_ of spec necessary. And was able to "guess"
> > missing parts (1 page of documentation is too few)
> >
> > I'll check Medium and Low quality and rename package + modify the build
> >
> > I have changed  1.3 to be 1.0 (no need for upscale IMHO).
> >
> > regarding copy/paste:
> > 1) I don't really like the idea of "static VirtualScreenBean" (it is not
> > bean, there is no need to make it static)
> > 2) various methods contains lots of similar code:
> >      a) VirtualScreen.updateVScreenBounds() similar calculations with
> lots
> > of casting
> >      b) CommonScreenShare.sendRemoteCursorEvent similar blocks of code
> > 3) I don't really like how the code is organized (I'm not 'comfortable'
> > with it maybe will review it in a spare time)
> >
> > On Fri, Mar 30, 2012 at 00:11, seba.wagner@gmail.com
> > <se...@gmail.com>wrote:
> >
> > > Hi Maxim,
> > >
> > > nice job :) Have you find something in the Specs for the protocol?
> > >
> > > Btw: Sharing or recording with medium or low quality throws some
> > exception
> > > now:
> > > java.lang.IllegalArgumentException: Width (0) and height (2048) cannot
> be
> > > <= 0
> > >    at
> > > java.awt.image.DirectColorModel.createCompatibleWritableRaster(Unknown
> > > Source)
> > >    at java.awt.image.BufferedImage.<init>(Unknown Source)
> > >    at
> > >
> org.red5.screen.webstart.ScreenV1Encoder.resize(ScreenV1Encoder.java:55)
> > >    at
> > >
> org.red5.screen.webstart.ScreenV1Encoder.encode(ScreenV1Encoder.java:68)
> > >    at
> > >
> > >
> >
> org.red5.screen.webstart.CommonScreenShare$CaptureScreen.run(CommonScreenShare.java:1195)
> > >    at java.lang.Thread.run(Unknown Source)
> > >
> > > About the quality settings in the client: Did you also change the
> > "normal"
> > > (high) quality that it does _not_ rescale the screen anymore?
> Previously
> > > the factor was 1.3 for the normal modus. I don't think that this is
> > > neccessary.
> > >
> > > I think we should also fix the the package name to fit into our
> > structure,
> > > what do you think?
> > >
> > > What did you mean by *The code still need to be reviewed to remove
> > > copy/pasted code* ?
> > >
> > > Thanks!
> > > Sebastian
> > >
> > >
> > > 2012/3/29 <so...@apache.org>
> > >
> > > > Author: solomax
> > > > Date: Thu Mar 29 08:14:45 2012
> > > > New Revision: 1306748
> > > >
> > > > URL: http://svn.apache.org/viewvc?rev=1306748&view=rev
> > > > Log:
> > > > Screen sharing client cleaned up from 'borrowed' code; code cleanup
> > > >
> > > > Added:
> > > >
> > > >
> > >
> >
>  incubator/openmeetings/trunk/singlewebapp/WebContent/red5-screenshare/logback.xml
> > > >
> > > >
> > >
> >
>  incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/IScreenEncoder.java
> > > >
> > > >
> > >
> >
>  incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/ScreenV1Encoder.java
> > > > Modified:
> > > >    incubator/openmeetings/trunk/singlewebapp/build.xml
> > > >
> > > >
> > >
> >
>  incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/installation/ImportInitvalues.java
> > > >
> > > >
> > >
> >
>  incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/CommonScreenShare.java
> > > >
> > > >
> > >
> >
>  incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreen.java
> > > >
> > > >
> > >
> >
>  incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreenBean.java
> > > >
> > > > Added:
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/WebContent/red5-screenshare/logback.xml
> > > > URL:
> > > >
> > >
> >
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/WebContent/red5-screenshare/logback.xml?rev=1306748&view=auto
> > > >
> > > >
> > >
> >
> ==============================================================================
> > > > ---
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/WebContent/red5-screenshare/logback.xml
> > > > (added)
> > > > +++
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/WebContent/red5-screenshare/logback.xml
> > > > Thu Mar 29 08:14:45 2012
> > > > @@ -0,0 +1,159 @@
> > > > +<?xml version="1.0" encoding="UTF-8"?>
> > > > +<configuration>
> > > > +       <!-- Uncomment if you are using the logback plugin for
> eclipse
> > > > +       <consolePlugin/>
> > > > +       -->
> > > > +       <appender name="CONSOLE"
> > > > class="ch.qos.logback.core.ConsoleAppender">
> > > > +               <encoder>
> > > > +                       <pattern>[%p] [%thread] %logger -
> > > %msg%n</pattern>
> > > > +               </encoder>
> > > > +       </appender>
> > > > +       <root>
> > > > +               <level value="WARN" />
> > > > +               <appender-ref ref="CONSOLE" />
> > > > +       </root>
> > > > +       <!-- Red5 -->
> > > > +       <logger name="org.red5.server.Launcher">
> > > > +               <level value="INFO" />
> > > > +       </logger>
> > > > +       <logger name="org.red5.io">
> > > > +               <level value="INFO" />
> > > > +       </logger>
> > > > +    <logger name="org.red5.logging.DerbyLogInterceptor">
> > > > +        <level value="WARN" />
> > > > +    </logger>
> > > > +    <logger name="org.red5.server">
> > > > +        <level value="WARN" />
> > > > +    </logger>
> > > > +       <logger name="org.red5.server.Client">
> > > > +               <level value="INFO" />
> > > > +       </logger>
> > > > +       <logger name="org.red5.server.api.stream.support">
> > > > +               <level value="INFO" />
> > > > +       </logger>
> > > > +       <logger name="org.red5.server.cache">
> > > > +               <level value="WARN" />
> > > > +       </logger>
> > > > +       <logger name="org.red5.server.jmx">
> > > > +               <level value="WARN" />
> > > > +       </logger>
> > > > +       <logger
> name="org.red5.server.messaging.InMemoryPushPushPipe">
> > > > +               <level value="INFO" />
> > > > +       </logger>
> > > > +       <logger name="org.red5.server.net">
> > > > +               <level value="INFO" />
> > > > +       </logger>
> > > > +       <logger name="org.red5.server.net.rtmpt.RTMPTServlet">
> > > > +               <level value="WARN" />
> > > > +       </logger>
> > > > +       <logger name="org.red5.server.net.servlet">
> > > > +               <level value="WARN" />
> > > > +       </logger>
> > > > +       <logger name="org.red5.server.net.proxy">
> > > > +               <level value="INFO" />
> > > > +       </logger>
> > > > +       <logger name="org.red5.server.net.remoting">
> > > > +               <level value="WARN" />
> > > > +       </logger>
> > > > +       <logger name="org.red5.server.net.rtmp">
> > > > +               <level value="WARN" />
> > > > +       </logger>
> > > > +       <logger name="org.red5.server.net.rtmp.BaseRTMPHandler">
> > > > +               <level value="WARN" />
> > > > +       </logger>
> > > > +       <logger name="org.red5.server.net.rtmp.RTMPMinaIoHandler">
> > > > +               <level value="WARN" />
> > > > +       </logger>
> > > > +       <logger name="org.red5.server.net.rtmp.status">
> > > > +               <level value="INFO" />
> > > > +       </logger>
> > > > +       <logger name="org.red5.server.net.rtmpt">
> > > > +               <level value="WARN" />
> > > > +       </logger>
> > > > +       <logger name="org.red5.server.persistence">
> > > > +               <level value="WARN" />
> > > > +       </logger>
> > > > +       <logger name="org.red5.server.script">
> > > > +               <level value="WARN" />
> > > > +       </logger>
> > > > +       <logger name="org.red5.server.service">
> > > > +               <level value="INFO" />
> > > > +       </logger>
> > > > +       <logger name="org.red5.server.so">
> > > > +               <level value="WARN" />
> > > > +       </logger>
> > > > +       <logger name="org.red5.server.stream">
> > > > +               <level value="INFO" />
> > > > +       </logger>
> > > > +       <logger name="org.red5.server.stream.consumer">
> > > > +               <level value="WARN" />
> > > > +       </logger>
> > > > +       <logger name="org.red5.server.net.mrtmp">
> > > > +               <level value="WARN" />
> > > > +       </logger>
> > > > +       <!-- Mina -->
> > > > +       <logger name="org.apache.mina">
> > > > +               <level value="WARN" />
> > > > +       </logger>
> > > > +       <logger name="org.apache.mina.filter">
> > > > +               <level value="WARN" />
> > > > +       </logger>
> > > > +       <logger
> > > > name="org.red5.server.adapter.MultiThreadedApplicationAdapter" >
> > > > +               <level value="INFO"/>
> > > > +       </logger>
> > > > +       <!-- Apache commons -->
> > > > +       <logger name="org.apache.commons">
> > > > +               <level value="WARN" />
> > > > +       </logger>
> > > > +       <logger name="httpclient">
> > > > +               <level value="WARN" />
> > > > +       </logger>
> > > > +       <!-- Apache catalina / tomcat -->
> > > > +    <logger name="org.red5.server.tomcat">
> > > > +        <level value="INFO" />
> > > > +    </logger>
> > > > +    <logger name="org.apache.catalina">
> > > > +        <level value="WARN" />
> > > > +    </logger>
> > > > +       <logger name="org.apache.jasper">
> > > > +               <level value="INFO" />
> > > > +       </logger>
> > > > +       <logger name="org.apache.tomcat">
> > > > +               <level value="INFO" />
> > > > +       </logger>
> > > > +       <logger name="org.apache.tomcat.util.net">
> > > > +               <level value="WARN" />
> > > > +       </logger>
> > > > +       <logger name="org.apache.coyote.http11">
> > > > +               <level value="INFO" />
> > > > +       </logger>
> > > > +       <!-- Spring -->
> > > > +       <logger name="org.springframework">
> > > > +               <level value="INFO" />
> > > > +       </logger>
> > > > +       <logger name="org.springframework.beans.factory">
> > > > +               <level value="INFO" />
> > > > +       </logger>
> > > > +       <logger name="org.springframework.beans.factory.xml">
> > > > +               <level value="WARN" />
> > > > +       </logger>
> > > > +       <logger name="org.springframework.ui.context.support">
> > > > +               <level value="WARN" />
> > > > +       </logger>
> > > > +       <logger name="org.springframework.web.context">
> > > > +               <level value="INFO" />
> > > > +       </logger>
> > > > +       <logger name="org.springframework.web.context.support">
> > > > +               <level value="WARN" />
> > > > +       </logger>
> > > > +       <logger name="org.quartz">
> > > > +               <level value="WARN" />
> > > > +       </logger>
> > > > +       <!-- Caching -->
> > > > +       <logger name="net.sf.ehcache">
> > > > +               <level value="INFO" />
> > > > +       </logger>
> > > > +       <logger name="ch.qos">
> > > > +               <level value="WARN" />
> > > > +       </logger>
> > > > +</configuration>
> > > >
> > > > Modified: incubator/openmeetings/trunk/singlewebapp/build.xml
> > > > URL:
> > > >
> > >
> >
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/build.xml?rev=1306748&r1=1306747&r2=1306748&view=diff
> > > >
> > > >
> > >
> >
> ==============================================================================
> > > > --- incubator/openmeetings/trunk/singlewebapp/build.xml (original)
> > > > +++ incubator/openmeetings/trunk/singlewebapp/build.xml Thu Mar 29
> > > > 08:14:45 2012
> > > > @@ -35,7 +35,7 @@
> > > >        <property name="mainlibs.lib.dir"
> > > > value="${project.lib.dir}/mainlibs" />
> > > >        <property name="om.lib.dir" value="${project.lib.dir}/om" />
> > > >        <property name="anakia.lib.dir"
> > value="${project.lib.dir}/anakia"
> > > />
> > > > -       <property name="red5-screenshare.images"
> > > > value="${basedir}/WebContent/red5-screenshare" />
> > > > +       <property name="red5-screenshare.resources"
> > > > value="${basedir}/WebContent/red5-screenshare" />
> > > >        <property name="junit.lib.dir"
> value="${project.lib.dir}/junit"
> > />
> > > >        <property name="rat.lib.dir" value="${project.lib.dir}/rat" />
> > > >        <property name="dtd-generator.lib.dir"
> > > > value="${project.lib.dir}/dtd-generator" />
> > > > @@ -294,7 +294,7 @@
> > > >                        <fileset dir="${main.out.dir}">
> > > >                                <include name="org/red5/screen/**" />
> > > >                        </fileset>
> > > > -                       <fileset
> file="${red5.lib}/conf/logback.xml"/>
> > > > +                       <fileset
> > > > file="${red5-screenshare.resources}/logback.xml"/>
> > > >                        <manifest>
> > > >                                <attribute name="Built-By"
> > > > value="OpenMeetings - http://openmeetings.googlecode.com" />
> > > >                                <attribute name="Built-On"
> > > > value="${build.TODAY}" />
> > > > @@ -321,7 +321,7 @@
> > > >                        </dname>
> > > >                </genkey>
> > > >                <copy todir="${screenshare.out.dir}" filtering="true">
> > > > -                       <fileset dir="${red5-screenshare.images}" />
> > > > +                       <fileset dir="${red5-screenshare.resources}"
> > > > includes="*.jpg"/>
> > > >                        <fileset dir="${red5.server.lib}"
> > > > includes="commons-codec*.jar" />
> > > >                        <fileset dir="${red5.server.lib}"
> > > > includes="httpclient*.jar" />
> > > >                        <fileset dir="${red5.server.lib}"
> > > > includes="httpcore*.jar" />
> > > >
> > > > Modified:
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/installation/ImportInitvalues.java
> > > > URL:
> > > >
> > >
> >
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/installation/ImportInitvalues.java?rev=1306748&r1=1306747&r2=1306748&view=diff
> > > >
> > > >
> > >
> >
> ==============================================================================
> > > > ---
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/installation/ImportInitvalues.java
> > > > (original)
> > > > +++
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/installation/ImportInitvalues.java
> > > > Thu Mar 29 08:14:45 2012
> > > > @@ -479,8 +479,9 @@ public class ImportInitvalues {
> > > >                cfgManagement.addConfByKey(3, "show.facebook.login",
> ""
> > +
> > > > 0, null,
> > > >                                "Show Facebook Login");
> > > >
> > > > -               cfgManagement.addConfByKey(3,
> > > > "default.quality.screensharing", "0",
> > > > -                               null, "Default selection in
> > ScreenSharing
> > > > Quality");
> > > > +               cfgManagement.addConfByKey(3,
> > > > "default.quality.screensharing", "1",
> > > > +                                               null,
> > > > +                                               "Default selection in
> > > > ScreenSharing Quality:\n 0 - bigger frame rate, no resize\n 1 - no
> > > resize\n
> > > > 2 - size == 1/2 of selected area\n 3 - size == 3/8 of selected
> area");
> > > >
> > > >                cfgManagement.addConfByKey(3, "default.dashboard.tab",
> > > "0",
> > > > null,
> > > >                                "Default selection in Dashboard tabs
> as
> > > > tab-index-id");
> > > >
> > > > Modified:
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/CommonScreenShare.java
> > > > URL:
> > > >
> > >
> >
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/CommonScreenShare.java?rev=1306748&r1=1306747&r2=1306748&view=diff
> > > >
> > > >
> > >
> >
> ==============================================================================
> > > > ---
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/CommonScreenShare.java
> > > > (original)
> > > > +++
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/CommonScreenShare.java
> > > > Thu Mar 29 08:14:45 2012
> > > > @@ -1,13 +1,11 @@
> > > >  package org.red5.screen.webstart;
> > > >
> > > >  import java.awt.Color;
> > > > -import java.awt.Graphics2D;
> > > >  import java.awt.Image;
> > > >  import java.awt.MouseInfo;
> > > >  import java.awt.Point;
> > > >  import java.awt.PointerInfo;
> > > >  import java.awt.Rectangle;
> > > > -import java.awt.RenderingHints;
> > > >  import java.awt.Robot;
> > > >  import java.awt.Toolkit;
> > > >  import java.awt.datatransfer.Clipboard;
> > > > @@ -22,14 +20,10 @@ import java.awt.event.KeyEvent;
> > > >  import java.awt.event.WindowAdapter;
> > > >  import java.awt.event.WindowEvent;
> > > >  import java.awt.image.BufferedImage;
> > > > -import java.awt.image.DataBuffer;
> > > > -import java.io.ByteArrayOutputStream;
> > > >  import java.io.IOException;
> > > > -import java.io.OutputStream;
> > > >  import java.util.HashMap;
> > > >  import java.util.Iterator;
> > > >  import java.util.Map;
> > > > -import java.util.zip.DeflaterOutputStream;
> > > >
> > > >  import javax.imageio.ImageIO;
> > > >  import javax.swing.ImageIcon;
> > > > @@ -45,6 +39,7 @@ import org.red5.io.ITagWriter;
> > > >  import org.red5.io.utils.ObjectMap;
> > > >  import org.red5.screen.webstart.gui.VirtualScreen;
> > > >  import org.red5.screen.webstart.gui.VirtualScreenBean;
> > > > +import org.red5.screen.webstart.gui.VirtualScreenBean.ScreenQuality;
> > > >  import org.red5.server.api.event.IEvent;
> > > >  import org.red5.server.api.service.IPendingServiceCall;
> > > >  import org.red5.server.net.rtmp.Channel;
> > > > @@ -117,7 +112,7 @@ public class CommonScreenShare {
> > > >        public String host = "btg199251";
> > > >        public String app = "oflaDemo";
> > > >        public int port = 1935;
> > > > -       public int defaultQualityScreensharing = 0;
> > > > +       public int defaultQualityScreensharing = 1;
> > > >
> > > >        public Long organization_id = 0L;
> > > >        public Long user_id = null;
> > > > @@ -157,11 +152,7 @@ public class CommonScreenShare {
> > > >        public String label1092 = "Medium Quality -";
> > > >        public String label1093 = "Low Quality -";
> > > >
> > > > -       public Float imgQuality = new Float(0.40);
> > > > -
> > > > -       // public Float scaleFactor = 1F;
> > > > -       public float Ampl_factor = 1.3f;
> > > > -
> > > > +       public float Ampl_factor = 1f;
> > > >        public boolean isConnected = false;
> > > >
> > > >        public Map<Integer, Boolean> currentPressedKeys = new
> > > > HashMap<Integer, Boolean>();
> > > > @@ -179,6 +170,9 @@ public class CommonScreenShare {
> > > >        public void main(String[] args) {
> > > >                try {
> > > >                        if (args.length == 9) {
> > > > +                               for (String arg : args) {
> > > > +                                       logger.debug("arg: " + arg);
> > > > +                               }
> > > >
> > > >                                host = args[0];
> > > >                                app = args[1];
> > > > @@ -308,13 +302,6 @@ public class CommonScreenShare {
> > > >                        // *****
> > > >                        // Text Recording
> > > >                        textAreaHeaderRecording = new JLabel();
> > > > -
> > > > -                       // FIXME: Set Font to bold
> > > > -                       // textAreaHeaderRecording.setB
> > > > -                       // Font f =
> textAreaHeaderRecording.getFont();
> > > > -                       //
> > > > textAreaHeaderRecording.setFont(f.deriveFont(f.getStyle() ^
> > > > -                       // Font.BOLD));
> > > > -
> > > >
>  textAreaHeaderRecording.setText(this.label869);
> > > >                        contentPane.add(textAreaHeaderRecording);
> > > >                        textAreaHeaderRecording.setBounds(10, 340,
> 480,
> > > 24);
> > > > @@ -421,9 +408,6 @@ public class CommonScreenShare {
> > > >                        PointerInfo a = MouseInfo.getPointerInfo();
> > > >                        Point mouseP = a.getLocation();
> > > >
> > > > -                       // Integer x =
> > > > Long.valueOf(Math.round(mouseP.getX())).intValue();
> > > > -                       // Integer y =
> > > > Long.valueOf(Math.round(mouseP.getY())).intValue();
> > > > -
> > > >                        Float scaleFactor =
> > > > Float.valueOf(VirtualScreenBean.vScreenResizeX)
> > > >                                        /
> > > > Float.valueOf(VirtualScreenBean.vScreenSpinnerWidth);
> > > >
> > > > @@ -643,18 +627,6 @@ public class CommonScreenShare {
> > > >
> > > >                                // VirtualScreenBean
> > > >
> > > > -                               // Integer x = Math.round ( ( (
> > > > -                               //
> > > > Float.valueOf(returnMap.get("x").toString()).floatValue()
> > > > -                               // *VirtualScreenBean.vScreenResizeX
> > > > -                               //
> > > > )/VirtualScreenBean.vScreenSpinnerWidth) / Ampl_factor) ;
> > > > -                               // Integer y = Math.round ( ( (
> > > > -                               //
> > > > Float.valueOf(returnMap.get("y").toString()).floatValue()
> > > > -                               // *VirtualScreenBean.vScreenResizeY
> > > > -                               //
> > > > )/VirtualScreenBean.vScreenSpinnerHeight)/ Ampl_factor) ;
> > > > -                               //
> > > > -
> > > > -                               // logger.debug("x 1
> > > "+returnMap.get("x"));
> > > > -
> > > >                                Float scaleFactor = Float
> > > >
> > > >  .valueOf(VirtualScreenBean.vScreenSpinnerWidth)
> > > >                                                /
> > > > Float.valueOf(VirtualScreenBean.vScreenResizeX);
> > > > @@ -951,13 +923,10 @@ public class CommonScreenShare {
> > > >                        ex.printStackTrace();
> > > >                }
> > > >                return "";
> > > > -               // clippy.setContents( clippysContent ,null);
> > > > //zur�cksetzen vom alten
> > > > -               // Kontext
> > > >        }
> > > >
> > > >        private void pressSpecialSign(String charValue, Robot
> instance)
> > {
> > > >                Clipboard clippy =
> > > > Toolkit.getDefaultToolkit().getSystemClipboard();
> > > > -               // Transferable clippysContent = clippy.getContents(
> > null
> > > > );
> > > >                try {
> > > >
> > > >                        Transferable transferableText = new
> > > > StringSelection(charValue);
> > > > @@ -1042,7 +1011,7 @@ public class CommonScreenShare {
> > > >                                        logger.debug("The Stream was
> > > > already started ");
> > > >                                }
> > > >
> > > > -                               if (returnMap.get("modus") != null) {
> > > > +                               if (returnMap != null &&
> > > > returnMap.get("modus") != null) {
> > > >                                        if
> > > > (returnMap.get("modus").toString()
> > > >
> > > >  .equals("startStreaming")) {
> > > >
> > > >  this.startButton.setEnabled(false);
> > > > @@ -1076,12 +1045,7 @@ public class CommonScreenShare {
> > > >                                logger.debug("setup capture thread
> > > > vScreenSpinnerHeight "
> > > >                                                +
> > > > VirtualScreenBean.vScreenSpinnerHeight);
> > > >
> > > > -                               capture = new
> > > > CaptureScreen(VirtualScreenBean.vScreenSpinnerX,
> > > > -
> > > > VirtualScreenBean.vScreenSpinnerY,
> > > > -
> > > > VirtualScreenBean.vScreenSpinnerWidth,
> > > > -
> > > > VirtualScreenBean.vScreenSpinnerHeight,
> > > > -
> > > > VirtualScreenBean.vScreenResizeX,
> > > > -
> > > > VirtualScreenBean.vScreenResizeY);
> > > > +                               capture = new CaptureScreen();
> > > >
> > > >                                if (thread == null) {
> > > >                                        thread = new Thread(capture);
> > > > @@ -1154,11 +1118,6 @@ public class CommonScreenShare {
> > > >
> > > >                kt++;
> > > >
> > > > -               // if ( kt < 10 ) {
> > > > -               // logger.debug( "+++ " + videoData );
> > > > -               // System.out.println( "+++ " + videoData);
> > > > -               // }
> > > > -
> > > >                RTMPMessage rtmpMsg = RTMPMessage.build(videoData);
> > > >                instance.publishStreamData(publishStreamId, rtmpMsg);
> > > >        }
> > > > @@ -1170,14 +1129,6 @@ public class CommonScreenShare {
> > > >        //
> > > >
> > ------------------------------------------------------------------------
> > > >
> > > >        private final class CaptureScreen extends Object implements
> > > > Runnable {
> > > > -               private volatile int x = 0;
> > > > -               private volatile int y = 0;
> > > > -               private volatile int resizeX;
> > > > -               private volatile int resizeY;
> > > > -
> > > > -               private volatile int width = resizeX; // 320
> > > > -               private volatile int height = resizeY; // 240
> > > > -
> > > >                private int timeBetweenFrames = 1000; // frameRate
> > > >
> > > >                private volatile long timestamp = 0;
> > > > @@ -1185,7 +1136,7 @@ public class CommonScreenShare {
> > > >                private volatile boolean active = true;
> > > >                @SuppressWarnings("unused")
> > > >                private volatile boolean stopped = false;
> > > > -               private byte[] previousItems = null;
> > > > +               private IScreenEncoder se;
> > > >
> > > >                //
> > > >
> > ------------------------------------------------------------------------
> > > >                //
> > > > @@ -1193,27 +1144,9 @@ public class CommonScreenShare {
> > > >                //
> > > >                //
> > > >
> > ------------------------------------------------------------------------
> > > >
> > > > -               public CaptureScreen(final int x, final int y, final
> > int
> > > > width,
> > > > -                               final int height, int resizeX, int
> > > > resizeY) {
> > > > -
> > > > -                       this.x = x;
> > > > -                       this.y = y;
> > > > -                       this.width = width;
> > > > -                       this.height = height;
> > > > -                       this.resizeX = resizeX;
> > > > -                       this.resizeY = resizeY;
> > > > -
> > > > -                       if (VirtualScreenBean.vScreenScaleFactor
> > > > -                                       .equals(label1090)) {
> > > > -                               timeBetweenFrames = 100;
> > > > -                       } else {
> > > > -                               timeBetweenFrames = 1000;
> > > > -                       }
> > > > -
> > > > -                       logger.debug("CaptureScreen: x=" + x + ", y="
> > + y
> > > > + ", w=" + width
> > > > -                                       + ", h=" + height +
> > ",resizeX=" +
> > > > resizeX + " resizeY= "
> > > > -                                       + resizeY);
> > > > -
> > > > +               public CaptureScreen() {
> > > > +                       timeBetweenFrames =
> > > > (VirtualScreenBean.screenQuality == ScreenQuality.VeryHigh) ? 100 :
> > 1000;
> > > > +                       se = new ScreenV1Encoder();
> > > >                }
> > > >
> > > >                //
> > > >
> > ------------------------------------------------------------------------
> > > > @@ -1234,7 +1167,7 @@ public class CommonScreenShare {
> > > >                }
> > > >
> > > >                public void resetBuffer() {
> > > > -                       this.previousItems = null;
> > > > +                       se.reset();
> > > >                }
> > > >
> > > >                //
> > > >
> > ------------------------------------------------------------------------
> > > > @@ -1242,89 +1175,27 @@ public class CommonScreenShare {
> > > >                // Thread loop
> > > >                //
> > > >                //
> > > >
> > ------------------------------------------------------------------------
> > > > -
> > > >                public void run() {
> > > > -                       final int blockWidth = 32;
> > > > -                       final int blockHeight = 32;
> > > > -
> > > > -                       int frameCounter = 0;
> > > > -
> > > > -                       int orig_width = width;
> > > > -                       int orig_height = height;
> > > > -
> > > >                        try {
> > > >                                Robot robot = new Robot();
> > > >
> > > > -                               this.previousItems = null;
> > > > -
> > > >                                while (active) {
> > > >                                        final long ctime =
> > > > System.currentTimeMillis();
> > > >
> > > > -                                       width = orig_width;
> > > > -                                       height = orig_height;
> > > > -
> > > > -                                       BufferedImage image = robot
> > > > -
> > > > .createScreenCapture(new Rectangle(x, y, width,
> > > > -
> > > > height));
> > > > -
> > > > -                                       int width_new = resizeX;
> > > > -                                       int height_new = resizeY;
> > > > -                                       width = resizeX;
> > > > -                                       height = resizeY;
> > > > -                                       // Resize to 640*480
> > > > -                                       // Create new (blank) image
> of
> > > > required (scaled) size
> > > > -                                       BufferedImage image_raw = new
> > > > BufferedImage(width_new,
> > > > -                                                       height_new,
> > > > BufferedImage.TYPE_INT_RGB);
> > > > -
> > > > -                                       Graphics2D graphics2D =
> > > > image_raw.createGraphics();
> > > > -                                       graphics2D.setRenderingHint(
> > > > -
> > > > RenderingHints.KEY_INTERPOLATION,
> > > > -
> > > > RenderingHints.VALUE_INTERPOLATION_BICUBIC);
> > > > -                                       graphics2D.drawImage(image,
> 0,
> > 0,
> > > > width_new, height_new,
> > > > -                                                       null);
> > > > -                                       graphics2D.dispose();
> > > > -
> > > > -                                       // End resize
> > > > -
> > > > -                                       int scaledWidth = width;
> > > > -                                       int scaledHeight = height;
> > > > -
> > > > -                                       byte[] current =
> > > toBGR(image_raw);
> > > > -                                       // if (scaleFactor != 1F) {
> > > > -                                       //
> > > > -                                       // logger.debug("Calc new
> > Scaled
> > > > Instance ",scaleFactor);
> > > > -                                       //
> > > > -                                       // scaledWidth =
> > > > -                                       //
> > > > Float.valueOf(Math.round(width*scaleFactor)).intValue();
> > > > -                                       // scaledHeight =
> > > > -                                       //
> > > > Float.valueOf(Math.round(height*scaleFactor)).intValue();
> > > > -                                       //
> > > > -                                       // Image img =
> > > > image_raw.getScaledInstance(scaledWidth,
> > > > -                                       //
> > > > scaledHeight,Image.SCALE_SMOOTH);
> > > > -                                       //
> > > > -                                       // BufferedImage
> image_scaled =
> > > new
> > > > -                                       // BufferedImage(scaledWidth,
> > > > -                                       //
> > > > scaledHeight,BufferedImage.TYPE_3BYTE_BGR);
> > > > -                                       //
> > > > -                                       // Graphics2D biContext =
> > > > image_scaled.createGraphics();
> > > > -                                       // biContext.drawImage(img,
> 0,
> > 0,
> > > > null);
> > > > -                                       // current =
> > toBGR(image_scaled);
> > > > -                                       // } else {
> > > > -                                       // current =
> toBGR(image_raw);
> > > > -                                       // }
> > > > +                                       Rectangle screen = new
> > > > Rectangle(VirtualScreenBean.vScreenSpinnerX,
> > > > +
> > > > VirtualScreenBean.vScreenSpinnerY,
> > > > +
> > > > VirtualScreenBean.vScreenSpinnerWidth,
> > > > +
> > > > VirtualScreenBean.vScreenSpinnerHeight);
> > > > +
> > > > +                                       BufferedImage image =
> > > > robot.createScreenCapture(screen);
> > > >
> > > >                                        try {
> > > > -                                               // timestamp +=
> > (1000000
> > > /
> > > > timeBetweenFrames);
> > > >                                                timestamp +=
> > > > timeBetweenFrames;
> > > >
> > > > -                                               final byte[]
> > screenBytes
> > > =
> > > > encode(current,
> > > > -
> > > > this.previousItems, blockWidth, blockHeight,
> > > > -
> > > > scaledWidth, scaledHeight);
> > > > -
> > > > pushVideo(screenBytes.length, screenBytes, timestamp);
> > > > -                                               this.previousItems =
> > > > current;
> > > > +                                               byte[] data =
> > > > se.encode(screen, image, new
> > Rectangle(VirtualScreenBean.vScreenResizeX,
> > > > +
> > > > VirtualScreenBean.vScreenResizeY));
> > > >
> > > > -                                               if (++frameCounter %
> > 100
> > > > == 0)
> > > > -
> > > this.previousItems
> > > > = null;
> > > > +
> pushVideo(data.length,
> > > > data, timestamp);
> > > >                                        } catch (Exception e) {
> > > >                                                e.printStackTrace();
> > > >                                        }
> > > > @@ -1339,132 +1210,5 @@ public class CommonScreenShare {
> > > >                                e.printStackTrace();
> > > >                        }
> > > >                }
> > > > -
> > > > -               //
> > > >
> > ------------------------------------------------------------------------
> > > > -               //
> > > > -               // Private
> > > > -               //
> > > > -               //
> > > >
> > ------------------------------------------------------------------------
> > > > -
> > > > -               private byte[] toBGR(BufferedImage image) {
> > > > -                       final int width = image.getWidth();
> > > > -                       final int height = image.getHeight();
> > > > -
> > > > -                       byte[] buf = new byte[3 * width * height];
> > > > -
> > > > -                       final DataBuffer buffer =
> > > > image.getData().getDataBuffer();
> > > > -
> > > > -                       for (int y = 0; y < height; y++) {
> > > > -                               for (int x = 0; x < width; x++) {
> > > > -                                       final int rgb =
> > buffer.getElem(y
> > > *
> > > > width + x);
> > > > -                                       final int offset = 3 * (y *
> > width
> > > > + x);
> > > > -
> > > > -                                       buf[offset + 0] = (byte)
> (rgb &
> > > > 0xFF);
> > > > -                                       buf[offset + 1] = (byte)
> ((rgb
> > >>
> > > > 8) & 0xFF);
> > > > -                                       buf[offset + 2] = (byte)
> ((rgb
> > >>
> > > > 16) & 0xFF);
> > > > -                               }
> > > > -                       }
> > > > -
> > > > -                       return buf;
> > > > -               }
> > > > -
> > > > -               private byte[] encode(final byte[] current, final
> > byte[]
> > > > previous,
> > > > -                               final int blockWidth, final int
> > > > blockHeight, final int width,
> > > > -                               final int height) throws Exception {
> > > > -                       ByteArrayOutputStream baos = new
> > > > ByteArrayOutputStream(16 * 1024);
> > > > -
> > > > -                       if (previous == null) {
> > > > -                               baos.write(getTag(0x01, 0x03)); //
> > > > keyframe (all cells)
> > > > -                       } else {
> > > > -                               baos.write(getTag(0x02, 0x03)); //
> > frame
> > > > (changed cells)
> > > > -                       }
> > > > -
> > > > -                       // write header
> > > > -                       final int wh = width + ((blockWidth / 16 - 1)
> > <<
> > > > 12);
> > > > -                       final int hh = height + ((blockHeight / 16 -
> 1)
> > > <<
> > > > 12);
> > > > -
> > > > -                       writeShort(baos, wh);
> > > > -                       writeShort(baos, hh);
> > > > -
> > > > -                       // write content
> > > > -                       int y0 = height;
> > > > -                       int x0 = 0;
> > > > -                       int bwidth = blockWidth;
> > > > -                       int bheight = blockHeight;
> > > > -
> > > > -                       while (y0 > 0) {
> > > > -                               bheight = Math.min(y0, blockHeight);
> > > > -                               y0 -= bheight;
> > > > -
> > > > -                               bwidth = blockWidth;
> > > > -                               x0 = 0;
> > > > -
> > > > -                               while (x0 < width) {
> > > > -                                       bwidth = (x0 + blockWidth >
> > > width)
> > > > ? width - x0
> > > > -                                                       : blockWidth;
> > > > -
> > > > -                                       final boolean changed =
> > > > isChanged(current, previous, x0,
> > > > -                                                       y0, bwidth,
> > > > bheight, width, height);
> > > > -
> > > > -                                       if (changed) {
> > > > -                                               ByteArrayOutputStream
> > > > blaos = new ByteArrayOutputStream(
> > > > -                                                               4 *
> > > 1024);
> > > > -
> > > > -                                               DeflaterOutputStream
> > dos
> > > =
> > > > new DeflaterOutputStream(
> > > > -
> blaos);
> > > > -
> > > > -                                               for (int y = 0; y <
> > > > bheight; y++) {
> > > > -
> > > dos.write(current,
> > > > 3 * ((y0 + bheight - y - 1)
> > > > -
> >   *
> > > > width + x0), 3 * bwidth);
> > > > -                                               }
> > > > -
> > > > -                                               dos.finish();
> > > > -
> > > > -                                               final byte[] bbuf =
> > > > blaos.toByteArray();
> > > > -                                               final int written =
> > > > bbuf.length;
> > > > -
> > > > -                                               // write DataSize
> > > > -                                               writeShort(baos,
> > > written);
> > > > -                                               // write Data
> > > > -                                               baos.write(bbuf, 0,
> > > > written);
> > > > -                                       } else {
> > > > -                                               // write DataSize
> > > > -                                               writeShort(baos, 0);
> > > > -                                       }
> > > > -
> > > > -                                       x0 += bwidth;
> > > > -                               }
> > > > -                       }
> > > > -
> > > > -                       return baos.toByteArray();
> > > > -               }
> > > > -
> > > > -               private void writeShort(OutputStream os, final int n)
> > > > throws Exception {
> > > > -                       os.write((n >> 8) & 0xFF);
> > > > -                       os.write((n >> 0) & 0xFF);
> > > > -               }
> > > > -
> > > > -               public boolean isChanged(final byte[] current, final
> > > > byte[] previous,
> > > > -                               final int x0, final int y0, final int
> > > > blockWidth,
> > > > -                               final int blockHeight, final int
> width,
> > > > final int height) {
> > > > -                       if (previous == null)
> > > > -                               return true;
> > > > -
> > > > -                       for (int y = y0, ny = y0 + blockHeight; y <
> ny;
> > > > y++) {
> > > > -                               final int foff = 3 * (x0 + width *
> y);
> > > > -                               final int poff = 3 * (x0 + width *
> y);
> > > > -
> > > > -                               for (int i = 0, ni = 3 * blockWidth;
> i
> > <
> > > > ni; i++) {
> > > > -                                       if (current[foff + i] !=
> > > > previous[poff + i])
> > > > -                                               return true;
> > > > -                               }
> > > > -                       }
> > > > -
> > > > -                       return false;
> > > > -               }
> > > > -
> > > > -               public int getTag(final int frame, final int codec) {
> > > > -                       return ((frame & 0x0F) << 4) + ((codec &
> 0x0F)
> > <<
> > > > 0);
> > > > -               }
> > > >        }
> > > >  }
> > > >
> > > > Added:
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/IScreenEncoder.java
> > > > URL:
> > > >
> > >
> >
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/IScreenEncoder.java?rev=1306748&view=auto
> > > >
> > > >
> > >
> >
> ==============================================================================
> > > > ---
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/IScreenEncoder.java
> > > > (added)
> > > > +++
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/IScreenEncoder.java
> > > > Thu Mar 29 08:14:45 2012
> > > > @@ -0,0 +1,30 @@
> > > > +/*
> > > > + * Licensed to the Apache Software Foundation (ASF) under one
> > > > + * or more contributor license agreements.  See the NOTICE file
> > > > + * distributed with this work for additional information
> > > > + * regarding copyright ownership.  The ASF licenses this file
> > > > + * to you under the Apache License, Version 2.0 (the
> > > > + * "License") +  you may not use this file except in compliance
> > > > + * with the License.  You may obtain a copy of the License at
> > > > + *
> > > > + *   http://www.apache.org/licenses/LICENSE-2.0
> > > > + *
> > > > + * Unless required by applicable law or agreed to in writing,
> > > > + * software distributed under the License is distributed on an
> > > > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > > > + * KIND, either express or implied.  See the License for the
> > > > + * specific language governing permissions and limitations
> > > > + * under the License.
> > > > + */
> > > > +package org.red5.screen.webstart;
> > > > +
> > > > +import java.awt.Rectangle;
> > > > +import java.awt.image.BufferedImage;
> > > > +import java.io.IOException;
> > > > +
> > > > +public interface IScreenEncoder {
> > > > +
> > > > +       byte[] encode(Rectangle screen, BufferedImage img, Rectangle
> > > size)
> > > >  throws IOException;
> > > > +
> > > > +       void reset();
> > > > +}
> > > >
> > > > Added:
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/ScreenV1Encoder.java
> > > > URL:
> > > >
> > >
> >
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/ScreenV1Encoder.java?rev=1306748&view=auto
> > > >
> > > >
> > >
> >
> ==============================================================================
> > > > ---
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/ScreenV1Encoder.java
> > > > (added)
> > > > +++
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/ScreenV1Encoder.java
> > > > Thu Mar 29 08:14:45 2012
> > > > @@ -0,0 +1,146 @@
> > > > +/*
> > > > + * Licensed to the Apache Software Foundation (ASF) under one
> > > > + * or more contributor license agreements.  See the NOTICE file
> > > > + * distributed with this work for additional information
> > > > + * regarding copyright ownership.  The ASF licenses this file
> > > > + * to you under the Apache License, Version 2.0 (the
> > > > + * "License") +  you may not use this file except in compliance
> > > > + * with the License.  You may obtain a copy of the License at
> > > > + *
> > > > + *   http://www.apache.org/licenses/LICENSE-2.0
> > > > + *
> > > > + * Unless required by applicable law or agreed to in writing,
> > > > + * software distributed under the License is distributed on an
> > > > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > > > + * KIND, either express or implied.  See the License for the
> > > > + * specific language governing permissions and limitations
> > > > + * under the License.
> > > > + */
> > > > +package org.red5.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;
> > > > +
> > > > +public class ScreenV1Encoder implements IScreenEncoder {
> > > > +       private BufferedImage last = null;
> > > > +       private static int KEY_FRAME_INDEX = 100;
> > > > +       private static int DEFAULT_BLOCK_SIZE = 32;
> > > > +       private int keyFrameIndex;
> > > > +       private int frameCount = 0;
> > > > +       private int blockSize;
> > > > +       private Rectangle screen;
> > > > +
> > > > +       public ScreenV1Encoder() {
> > > > +               this(KEY_FRAME_INDEX, DEFAULT_BLOCK_SIZE);
> > > > +       }
> > > > +
> > > > +       //will create square blocks
> > > > +       public ScreenV1Encoder(int keyFrameIndex, int blockSize) {
> > > > +               this.keyFrameIndex = keyFrameIndex;
> > > > +               if (blockSize < 16 || blockSize > 256 || blockSize %
> 16
> > > !=
> > > > 0) {
> > > > +                       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;
> > > > +       }
> > > > +
> > > > +       public byte[] encode(Rectangle screen, BufferedImage _img,
> > > > Rectangle size) throws IOException {
> > > > +               BufferedImage img = resize(_img, size);
> > > > +               Rectangle imgArea = new Rectangle(img.getWidth(),
> > > > img.getHeight());
> > > > +               Rectangle area = getNextBlock(imgArea, null);
> > > > +               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));
> > > > +               writeShort(ba, imgArea.height + ((blockSize / 16 - 1)
> > <<
> > > > 12));
> > > > +
> > > > +               while (area.width > 0 && area.height > 0) {
> > > > +                       writeBytesIfChanged(ba, isKeyFrame, img,
> area);
> > > > +                       area = getNextBlock(imgArea, area);
> > > > +               }
> > > > +               this.screen = screen;
> > > > +               last = img;
> > > > +               return ba.toByteArray();
> > > > +       }
> > > > +
> > > > +       public void reset() {
> > > > +               last = null;
> > > > +       }
> > > > +
> > > > +       private Rectangle getNextBlock(Rectangle img, Rectangle
> _prev)
> > {
> > > > +               Rectangle prev;
> > > > +               if (_prev == null) {
> > > > +                       prev = new Rectangle(0, Math.max(0,
> img.height
> > -
> > > > blockSize), blockSize, blockSize);
> > > > +               } else {
> > > > +                       prev = new Rectangle(_prev);
> > > > +                       if (prev.x + prev.width == img.getWidth()) {
> > > > +                               if (prev.y == 0) return new
> > Rectangle();
> > > > //the end of the image
> > > > +                               //next row
> > > > +                               prev.x = 0; //reset position
> > > > +                               prev.width = blockSize; //reset width
> > > > +                               prev.y -= (prev.y > blockSize ?
> > blockSize
> > > > : prev.y);
> > > > +                       } else {
> > > > +                               prev.x += blockSize;
> > > > +                       }
> > > > +               }
> > > > +               return img.intersection(prev);
> > > > +       }
> > > > +
> > > > +       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);
> > > > +               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
> > > > +                               });
> > > > +                       }
> > > > +               }
> > > > +               dos.finish();
> > > > +               if (changed) {
> > > > +                       final int written = baos.size();
> > > > +                       writeShort(ba, written);
> > > > +                       ba.write(baos.toByteArray(), 0, written);
> > > > +               } else {
> > > > +                       writeShort(ba, 0);
> > > > +               }
> > > > +       }
> > > > +
> > > > +       public int getTag(final int frame, final int codec) {
> > > > +               return ((frame & 0x0F) << 4) + ((codec & 0x0F) << 0);
> > > > +       }
> > > > +
> > > > +       private void writeShort(OutputStream os, final int n) throws
> > > > IOException {
> > > > +               os.write((n >> 8) & 0xFF);
> > > > +               os.write((n >> 0) & 0xFF);
> > > > +       }
> > > > +}
> > > >
> > > > Modified:
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreen.java
> > > > URL:
> > > >
> > >
> >
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreen.java?rev=1306748&r1=1306747&r2=1306748&view=diff
> > > >
> > > >
> > >
> >
> ==============================================================================
> > > > ---
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreen.java
> > > > (original)
> > > > +++
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreen.java
> > > > Thu Mar 29 08:14:45 2012
> > > > @@ -18,27 +18,29 @@
> > > >  */
> > > >  package org.red5.screen.webstart.gui;
> > > >
> > > > -import javax.imageio.ImageIO;
> > > >  import java.awt.Color;
> > > >  import java.awt.Dimension;
> > > >  import java.awt.Image;
> > > >  import java.awt.Rectangle;
> > > >  import java.awt.Robot;
> > > > +import java.awt.event.ActionEvent;
> > > > +import java.awt.event.ActionListener;
> > > >  import java.awt.image.BufferedImage;
> > > >
> > > > -import javax.swing.SwingConstants;
> > > > +import javax.imageio.ImageIO;
> > > >  import javax.swing.ImageIcon;
> > > > -import javax.swing.JLabel;
> > > >  import javax.swing.JComboBox;
> > > > +import javax.swing.JLabel;
> > > >  import javax.swing.JSpinner;
> > > >  import javax.swing.SpinnerNumberModel;
> > > > +import javax.swing.SwingConstants;
> > > >  import javax.swing.event.ChangeEvent;
> > > >  import javax.swing.event.ChangeListener;
> > > > -import java.awt.event.*;
> > > >
> > > >  import org.red5.screen.webstart.BlankArea;
> > > >  import org.red5.screen.webstart.CommonScreenShare;
> > > >  import org.red5.screen.webstart.ScreenShare;
> > > > +import org.red5.screen.webstart.gui.VirtualScreenBean.ScreenQuality;
> > > >  import org.slf4j.Logger;
> > > >  import org.slf4j.LoggerFactory;
> > > >
> > > > @@ -50,6 +52,40 @@ public class VirtualScreen {
> > > >
> > > >        public boolean doUpdateBounds = true;
> > > >
> > > > +       private class KeyValue<T> {
> > > > +               private String key;
> > > > +               private T value;
> > > > +
> > > > +               public KeyValue(String key, T value) {
> > > > +                       this.key = key;
> > > > +                       this.value = value;
> > > > +               }
> > > > +
> > > > +               @SuppressWarnings("unused")
> > > > +               public String getKey() { return key; }
> > > > +               public T getValue() { return value; }
> > > > +
> > > > +               @Override
> > > > +               public String toString() { return key; }
> > > > +
> > > > +               @Override
> > > > +               public boolean equals(Object obj) {
> > > > +                       if (obj instanceof KeyValue) {
> > > > +                               @SuppressWarnings("unchecked")
> > > > +                               KeyValue<T> kv = (KeyValue<T>) obj;
> > > > +                               return (kv.value.equals(this.value));
> > > > +                       }
> > > > +                       return false;
> > > > +               }
> > > > +
> > > > +               @Override
> > > > +               public int hashCode() {
> > > > +                       int hash = 7;
> > > > +                       hash = 97 * hash + (this.value != null ?
> > > > this.value.hashCode() : 0);
> > > > +                       return hash;
> > > > +               }
> > > > +       }
> > > > +
> > > >        public VirtualScreen(CommonScreenShare css) throws Exception {
> > > >                this.css = css;
> > > >
> > > > @@ -175,7 +211,6 @@ public class VirtualScreen {
> > > >                css.jVScreenXSpin.setBounds(400, 170, 60, 24);
> > > >                css.jVScreenXSpin.addChangeListener( new
> > ChangeListener(){
> > > >                        public void stateChanged(ChangeEvent arg0) {
> > > > -                               // TODO Auto-generated method stub
> > > >                                calcNewValueXSpin();
> > > >                        }
> > > >                });
> > > > @@ -194,7 +229,6 @@ public class VirtualScreen {
> > > >                css.jVScreenYSpin.setBounds(400, 200, 60, 24);
> > > >                css.jVScreenYSpin.addChangeListener( new
> > ChangeListener(){
> > > >                        public void stateChanged(ChangeEvent arg0) {
> > > > -                               // TODO Auto-generated method stub
> > > >                                calcNewValueYSpin();
> > > >                        }
> > > >                });
> > > > @@ -213,7 +247,6 @@ public class VirtualScreen {
> > > >                css.jVScreenWidthSpin.setBounds(400, 240, 60, 24);
> > > >                css.jVScreenWidthSpin.addChangeListener( new
> > > > ChangeListener(){
> > > >                        public void stateChanged(ChangeEvent arg0) {
> > > > -                               // TODO Auto-generated method stub
> > > >                                calcNewValueWidthSpin();
> > > >                        }
> > > >                });
> > > > @@ -232,15 +265,12 @@ public class VirtualScreen {
> > > >                css.jVScreenHeightSpin.setBounds(400, 270, 60, 24);
> > > >                css.jVScreenHeightSpin.addChangeListener( new
> > > > ChangeListener(){
> > > >                        public void stateChanged(ChangeEvent arg0) {
> > > > -                               // TODO Auto-generated method stub
> > > >                                calcNewValueHeightSpin();
> > > >                        }
> > > >                });
> > > >                css.t.add(css.jVScreenHeightSpin);
> > > >
> > > >
> > > > -               //String[] selectResize = { css.label1090,
> > css.label1091,
> > > > css.label1092, css.label1093 };
> > > > -               String[] selectResize = { css.label1091,
> css.label1092,
> > > > css.label1093 };
> > > >                VirtualScreenBean.vScreenResizeX = 640;
> > > >                VirtualScreenBean.vScreenResizeY = 400;
> > > >
> > > > @@ -249,84 +279,55 @@ public class VirtualScreen {
> > > >                css.vscreenResizeLabel.setBounds(250, 300, 200,24 );
> > > >                css.t.add(css.vscreenResizeLabel);
> > > >
> > > > -               JComboBox comboResize  = new JComboBox(selectResize);
> > > > +               JComboBox comboResize  = new JComboBox();
> > > > +               comboResize.addItem(new
> > > > KeyValue<ScreenQuality>(css.label1090, ScreenQuality.VeryHigh));
> > > > +               comboResize.addItem(new
> > > > KeyValue<ScreenQuality>(css.label1091, ScreenQuality.High));
> > > > +               comboResize.addItem(new
> > > > KeyValue<ScreenQuality>(css.label1092, ScreenQuality.Medium));
> > > > +               comboResize.addItem(new
> > > > KeyValue<ScreenQuality>(css.label1093, ScreenQuality.Low));
> > > >                comboResize.setBounds(250, 330, 200, 24);
> > > > -               comboResize.addActionListener(new GetResizeChoice());
> > > > +               comboResize.addActionListener(new ActionListener(){
> > > > +                       @SuppressWarnings("unchecked")
> > > > +                       public void actionPerformed(ActionEvent e) {
> > > > +                               JComboBox cb =
> > (JComboBox)e.getSource();
> > > > +                       VirtualScreenBean.screenQuality =
> > > > ((KeyValue<ScreenQuality>)cb.getSelectedItem()).getValue();
> > > > +                       calcRescaleFactors();
> > > > +                       }
> > > > +               });
> > > >
> > > >  comboResize.setSelectedIndex(css.defaultQualityScreensharing);
> > > >
> > > >                css.jVScreenResizeMode = comboResize;
> > > >                css.t.add(css.jVScreenResizeMode);
> > > >
> > > >        }
> > > > -       class GetResizeChoice implements ActionListener
> > > > -       {
> > > > -               public void actionPerformed (ActionEvent e)
> > > > -               {
> > > > -
> > > > -                       JComboBox cb = (JComboBox)e.getSource();
> > > > -               String petName = (String)cb.getSelectedItem();
> > > > -
> > > > -               VirtualScreenBean.vScreenScaleFactor = petName;
> > > > -
> > > > -               calcRescaleFactors();
> > > > -
> > > > -               }
> > > > -       }
> > > >
> > > >        /**
> > > >         * Needs to be always invoked after every re-scaling
> > > >         */
> > > >        void calcRescaleFactors() {
> > > > -
> > > >                logger.debug("calcRescaleFactors -- ");
> > > > -
> > > > if(VirtualScreenBean.vScreenScaleFactor.equals(css.label1090))
> > > > -        {
> > > > -                       logger.debug("resize:
> > > >
> > >
> >
> X:"+Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue()+
> > > > -                                       "
> > > >
> > >
> >
> Y:"+Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue());
> > > > -
> > > > -                       VirtualScreenBean.vScreenResizeX =
> > > >
> > Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue();
> > > > -                       VirtualScreenBean.vScreenResizeY =
> > > >
> > Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue();
> > > > -                       updateVScreenBounds();
> > > > -        }
> > > > -               else
> > > > if(VirtualScreenBean.vScreenScaleFactor.equals(css.label1091))
> > > > -        {
> > > > -               logger.debug("resize:
> > > >
> > >
> >
> X:"+Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue()+
> > > > -                                                       "
> > > >
> > >
> >
> Y:"+Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue());
> > > > -
> > > > -               VirtualScreenBean.vScreenResizeX =
> > > >
> > Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue();
> > > > -               VirtualScreenBean.vScreenResizeY =
> > > >
> > Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue();
> > > > -               updateVScreenBounds();
> > > > -        }
> > > > -        else
> > > > if(VirtualScreenBean.vScreenScaleFactor.equals(css.label1092))
> > > > -        {
> > > > -               logger.debug("resize:
> > > >
> > >
> >
> X:"+Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue()/2+
> > > > -                                                       "
> > > >
> > >
> >
> Y:"+Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue()/2);
> > > > -
> > > > -               VirtualScreenBean.vScreenResizeX =
> > > >
> > >
> >
> (Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue())/2;
> > > > -               VirtualScreenBean.vScreenResizeY =
> > > >
> > >
> >
> (Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue())/2;
> > > > -               updateVScreenBounds();
> > > > -        }
> > > > -        else
> > > > if(VirtualScreenBean.vScreenScaleFactor.equals(css.label1093))
> > > > -        {
> > > > -               logger.debug("resize:
> > > >
> > >
> >
> X:"+(Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue()/8)*3+
> > > > -                                                       "
> > > >
> > >
> >
> Y:"+(Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue()/8)*3);
> > > > -
> > > > -               VirtualScreenBean.vScreenResizeX =
> > > >
> > >
> >
> (Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue()/8)*3;
> > > > -               VirtualScreenBean.vScreenResizeY =
> > > >
> > >
> >
> (Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue()/8)*3;
> > > > -               updateVScreenBounds();
> > > > -        }
> > > > -
> > > > -                logger.debug("########## calcRescaleFactors
> > > > vScreenResizeX " + VirtualScreenBean.vScreenResizeX);
> > > > -         logger.debug("########## calcRescaleFactors vScreenResizeY
> "
> > +
> > > > VirtualScreenBean.vScreenResizeY);
> > > > -         logger.debug("########## calcRescaleFactors
> > vScreenScaleFactor
> > > "
> > > > + VirtualScreenBean.vScreenScaleFactor);
> > > > -
> > > > +               VirtualScreenBean.vScreenResizeX =
> > > >
> > Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue();
> > > > +               VirtualScreenBean.vScreenResizeY =
> > > >
> > Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue();
> > > > +               switch (VirtualScreenBean.screenQuality) {
> > > > +                       case VeryHigh:
> > > > +                       case High:
> > > > +                               break;
> > > > +                       case Medium:
> > > > +                               VirtualScreenBean.vScreenResizeX *=
> > 1/2;
> > > > +                               VirtualScreenBean.vScreenResizeY *=
> 2;
> > > > +                               break;
> > > > +                       case Low:
> > > > +                               VirtualScreenBean.vScreenResizeX *=
> > 3/8;
> > > > +                               VirtualScreenBean.vScreenResizeY *=
> > 3/8;
> > > > +                               break;
> > > > +               }
> > > > +               logger.debug("resize: X:" +
> > > > VirtualScreenBean.vScreenResizeX + " Y: " +
> > > > VirtualScreenBean.vScreenResizeY);
> > > > +               updateVScreenBounds();
> > > >        }
> > > >
> > > >        void calcNewValueXSpin(){
> > > >                if (this.doUpdateBounds){
> > > >                        int newX =
> > > > Integer.valueOf(css.jVScreenXSpin.getValue().toString()).intValue();
> > > >                        if(VirtualScreenBean.vScreenSpinnerWidth+newX
> >
> > > > VirtualScreenBean.screenWidthMax){
> > > > -//                             System.out.println("WARNING X
> > > > "+VirtualScreenBean.vScreenSpinnerWidth+" "+newX);
> > > >
> > > >
> > >
> >
>  newX=VirtualScreenBean.screenWidthMax-VirtualScreenBean.vScreenSpinnerWidth;
> > > >                                css.jVScreenXSpin.setValue(newX);
> > > >                                if (this.showWarning)
> > > > css.showBandwidthWarning("Reduce the width of the SharingScreen
> before
> > > you
> > > > try to move it left");
> > > > @@ -363,7 +364,6 @@ public class VirtualScreen {
> > > >                if (this.doUpdateBounds){
> > > >                        int newWidth =
> > > >
> > Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue();
> > > >                        if(VirtualScreenBean.vScreenSpinnerX+newWidth
> >
> > > > VirtualScreenBean.screenWidthMax){
> > > > -//                             System.out.println("WARNING WIDTH");
> > > >
> > > >
> > >
> >
>  newWidth=VirtualScreenBean.screenWidthMax-VirtualScreenBean.vScreenSpinnerX;
> > > >
> >  css.jVScreenWidthSpin.setValue(newWidth);
> > > >                                if
> > > > (this.showWarning)css.showBandwidthWarning("Reduce the x of the
> > > > SharingScreen before you try to make it wider");
> > > >
> > > > Modified:
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreenBean.java
> > > > URL:
> > > >
> > >
> >
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreenBean.java?rev=1306748&r1=1306747&r2=1306748&view=diff
> > > >
> > > >
> > >
> >
> ==============================================================================
> > > > ---
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreenBean.java
> > > > (original)
> > > > +++
> > > >
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreenBean.java
> > > > Thu Mar 29 08:14:45 2012
> > > > @@ -18,11 +18,8 @@
> > > >  */
> > > >  package org.red5.screen.webstart.gui;
> > > >
> > > > -import java.awt.Robot;
> > > >
> > > >  public class VirtualScreenBean {
> > > > -
> > > > -
> > > >        /**
> > > >         * image recalcing value's from the virtual Screen drawer
> > > >         */
> > > > @@ -47,13 +44,15 @@ public class VirtualScreenBean {
> > > >        public static int vScreenSpinnerX = 0;
> > > >        public static int vScreenSpinnerY = 0;
> > > >
> > > > -       public static String vScreenScaleFactor = "Medium Quality";
> > > > +       public static ScreenQuality screenQuality =
> > ScreenQuality.Medium;
> > > >
> > > >        public static int vScreenResizeX = 480;
> > > >        public static int vScreenResizeY = 360;
> > > >
> > > > -
> > > > -       public static Robot robot = null;
> > > > -
> > > > -       public static Float imgQuality = new Float(0.40);
> > > > +       public enum ScreenQuality {
> > > > +               VeryHigh
> > > > +               , High
> > > > +               , Medium
> > > > +               , Low
> > > > +       }
> > > >  }
> > > >
> > > >
> > > >
> > >
> > >
> > > --
> > > Sebastian Wagner
> > > https://twitter.com/#!/dead_lock
> > > http://www.openmeetings.de <http://incubator.apache.org/openmeetings/>
> > > http://www.webbase-design.de
> > > http://www.wagner-sebastian.com
> > > seba.wagner@gmail.com
> > >
> >
> >
> >
> > --
> > WBR
> > Maxim aka solomax
> >
>
>
>
> --
> Sebastian Wagner
> https://twitter.com/#!/dead_lock
> http://www.openmeetings.de <http://incubator.apache.org/openmeetings/>
> http://www.webbase-design.de
> http://www.wagner-sebastian.com
> seba.wagner@gmail.com
>



-- 
WBR
Maxim aka solomax

Re: svn commit: r1306748 - in /incubator/openmeetings/trunk/singlewebapp: ./ WebContent/red5-screenshare/ src/org/openmeetings/app/installation/ src/org/red5/screen/webstart/ src/org/red5/screen/webstart/gui/

Posted by "seba.wagner@gmail.com" <se...@gmail.com>.
That would be nice, I have written the code 3-4 years ago so it would be
nice if you find the time to refactor it.

1 page of documentation is too few? You mean the part about SHA1 in the
RTMP spec ?

2012/3/30 Maxim Solodovnik <so...@gmail.com>

> I was able to find _some_ of spec necessary. And was able to "guess"
> missing parts (1 page of documentation is too few)
>
> I'll check Medium and Low quality and rename package + modify the build
>
> I have changed  1.3 to be 1.0 (no need for upscale IMHO).
>
> regarding copy/paste:
> 1) I don't really like the idea of "static VirtualScreenBean" (it is not
> bean, there is no need to make it static)
> 2) various methods contains lots of similar code:
>      a) VirtualScreen.updateVScreenBounds() similar calculations with lots
> of casting
>      b) CommonScreenShare.sendRemoteCursorEvent similar blocks of code
> 3) I don't really like how the code is organized (I'm not 'comfortable'
> with it maybe will review it in a spare time)
>
> On Fri, Mar 30, 2012 at 00:11, seba.wagner@gmail.com
> <se...@gmail.com>wrote:
>
> > Hi Maxim,
> >
> > nice job :) Have you find something in the Specs for the protocol?
> >
> > Btw: Sharing or recording with medium or low quality throws some
> exception
> > now:
> > java.lang.IllegalArgumentException: Width (0) and height (2048) cannot be
> > <= 0
> >    at
> > java.awt.image.DirectColorModel.createCompatibleWritableRaster(Unknown
> > Source)
> >    at java.awt.image.BufferedImage.<init>(Unknown Source)
> >    at
> > org.red5.screen.webstart.ScreenV1Encoder.resize(ScreenV1Encoder.java:55)
> >    at
> > org.red5.screen.webstart.ScreenV1Encoder.encode(ScreenV1Encoder.java:68)
> >    at
> >
> >
> org.red5.screen.webstart.CommonScreenShare$CaptureScreen.run(CommonScreenShare.java:1195)
> >    at java.lang.Thread.run(Unknown Source)
> >
> > About the quality settings in the client: Did you also change the
> "normal"
> > (high) quality that it does _not_ rescale the screen anymore? Previously
> > the factor was 1.3 for the normal modus. I don't think that this is
> > neccessary.
> >
> > I think we should also fix the the package name to fit into our
> structure,
> > what do you think?
> >
> > What did you mean by *The code still need to be reviewed to remove
> > copy/pasted code* ?
> >
> > Thanks!
> > Sebastian
> >
> >
> > 2012/3/29 <so...@apache.org>
> >
> > > Author: solomax
> > > Date: Thu Mar 29 08:14:45 2012
> > > New Revision: 1306748
> > >
> > > URL: http://svn.apache.org/viewvc?rev=1306748&view=rev
> > > Log:
> > > Screen sharing client cleaned up from 'borrowed' code; code cleanup
> > >
> > > Added:
> > >
> > >
> >
>  incubator/openmeetings/trunk/singlewebapp/WebContent/red5-screenshare/logback.xml
> > >
> > >
> >
>  incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/IScreenEncoder.java
> > >
> > >
> >
>  incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/ScreenV1Encoder.java
> > > Modified:
> > >    incubator/openmeetings/trunk/singlewebapp/build.xml
> > >
> > >
> >
>  incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/installation/ImportInitvalues.java
> > >
> > >
> >
>  incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/CommonScreenShare.java
> > >
> > >
> >
>  incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreen.java
> > >
> > >
> >
>  incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreenBean.java
> > >
> > > Added:
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/WebContent/red5-screenshare/logback.xml
> > > URL:
> > >
> >
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/WebContent/red5-screenshare/logback.xml?rev=1306748&view=auto
> > >
> > >
> >
> ==============================================================================
> > > ---
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/WebContent/red5-screenshare/logback.xml
> > > (added)
> > > +++
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/WebContent/red5-screenshare/logback.xml
> > > Thu Mar 29 08:14:45 2012
> > > @@ -0,0 +1,159 @@
> > > +<?xml version="1.0" encoding="UTF-8"?>
> > > +<configuration>
> > > +       <!-- Uncomment if you are using the logback plugin for eclipse
> > > +       <consolePlugin/>
> > > +       -->
> > > +       <appender name="CONSOLE"
> > > class="ch.qos.logback.core.ConsoleAppender">
> > > +               <encoder>
> > > +                       <pattern>[%p] [%thread] %logger -
> > %msg%n</pattern>
> > > +               </encoder>
> > > +       </appender>
> > > +       <root>
> > > +               <level value="WARN" />
> > > +               <appender-ref ref="CONSOLE" />
> > > +       </root>
> > > +       <!-- Red5 -->
> > > +       <logger name="org.red5.server.Launcher">
> > > +               <level value="INFO" />
> > > +       </logger>
> > > +       <logger name="org.red5.io">
> > > +               <level value="INFO" />
> > > +       </logger>
> > > +    <logger name="org.red5.logging.DerbyLogInterceptor">
> > > +        <level value="WARN" />
> > > +    </logger>
> > > +    <logger name="org.red5.server">
> > > +        <level value="WARN" />
> > > +    </logger>
> > > +       <logger name="org.red5.server.Client">
> > > +               <level value="INFO" />
> > > +       </logger>
> > > +       <logger name="org.red5.server.api.stream.support">
> > > +               <level value="INFO" />
> > > +       </logger>
> > > +       <logger name="org.red5.server.cache">
> > > +               <level value="WARN" />
> > > +       </logger>
> > > +       <logger name="org.red5.server.jmx">
> > > +               <level value="WARN" />
> > > +       </logger>
> > > +       <logger name="org.red5.server.messaging.InMemoryPushPushPipe">
> > > +               <level value="INFO" />
> > > +       </logger>
> > > +       <logger name="org.red5.server.net">
> > > +               <level value="INFO" />
> > > +       </logger>
> > > +       <logger name="org.red5.server.net.rtmpt.RTMPTServlet">
> > > +               <level value="WARN" />
> > > +       </logger>
> > > +       <logger name="org.red5.server.net.servlet">
> > > +               <level value="WARN" />
> > > +       </logger>
> > > +       <logger name="org.red5.server.net.proxy">
> > > +               <level value="INFO" />
> > > +       </logger>
> > > +       <logger name="org.red5.server.net.remoting">
> > > +               <level value="WARN" />
> > > +       </logger>
> > > +       <logger name="org.red5.server.net.rtmp">
> > > +               <level value="WARN" />
> > > +       </logger>
> > > +       <logger name="org.red5.server.net.rtmp.BaseRTMPHandler">
> > > +               <level value="WARN" />
> > > +       </logger>
> > > +       <logger name="org.red5.server.net.rtmp.RTMPMinaIoHandler">
> > > +               <level value="WARN" />
> > > +       </logger>
> > > +       <logger name="org.red5.server.net.rtmp.status">
> > > +               <level value="INFO" />
> > > +       </logger>
> > > +       <logger name="org.red5.server.net.rtmpt">
> > > +               <level value="WARN" />
> > > +       </logger>
> > > +       <logger name="org.red5.server.persistence">
> > > +               <level value="WARN" />
> > > +       </logger>
> > > +       <logger name="org.red5.server.script">
> > > +               <level value="WARN" />
> > > +       </logger>
> > > +       <logger name="org.red5.server.service">
> > > +               <level value="INFO" />
> > > +       </logger>
> > > +       <logger name="org.red5.server.so">
> > > +               <level value="WARN" />
> > > +       </logger>
> > > +       <logger name="org.red5.server.stream">
> > > +               <level value="INFO" />
> > > +       </logger>
> > > +       <logger name="org.red5.server.stream.consumer">
> > > +               <level value="WARN" />
> > > +       </logger>
> > > +       <logger name="org.red5.server.net.mrtmp">
> > > +               <level value="WARN" />
> > > +       </logger>
> > > +       <!-- Mina -->
> > > +       <logger name="org.apache.mina">
> > > +               <level value="WARN" />
> > > +       </logger>
> > > +       <logger name="org.apache.mina.filter">
> > > +               <level value="WARN" />
> > > +       </logger>
> > > +       <logger
> > > name="org.red5.server.adapter.MultiThreadedApplicationAdapter" >
> > > +               <level value="INFO"/>
> > > +       </logger>
> > > +       <!-- Apache commons -->
> > > +       <logger name="org.apache.commons">
> > > +               <level value="WARN" />
> > > +       </logger>
> > > +       <logger name="httpclient">
> > > +               <level value="WARN" />
> > > +       </logger>
> > > +       <!-- Apache catalina / tomcat -->
> > > +    <logger name="org.red5.server.tomcat">
> > > +        <level value="INFO" />
> > > +    </logger>
> > > +    <logger name="org.apache.catalina">
> > > +        <level value="WARN" />
> > > +    </logger>
> > > +       <logger name="org.apache.jasper">
> > > +               <level value="INFO" />
> > > +       </logger>
> > > +       <logger name="org.apache.tomcat">
> > > +               <level value="INFO" />
> > > +       </logger>
> > > +       <logger name="org.apache.tomcat.util.net">
> > > +               <level value="WARN" />
> > > +       </logger>
> > > +       <logger name="org.apache.coyote.http11">
> > > +               <level value="INFO" />
> > > +       </logger>
> > > +       <!-- Spring -->
> > > +       <logger name="org.springframework">
> > > +               <level value="INFO" />
> > > +       </logger>
> > > +       <logger name="org.springframework.beans.factory">
> > > +               <level value="INFO" />
> > > +       </logger>
> > > +       <logger name="org.springframework.beans.factory.xml">
> > > +               <level value="WARN" />
> > > +       </logger>
> > > +       <logger name="org.springframework.ui.context.support">
> > > +               <level value="WARN" />
> > > +       </logger>
> > > +       <logger name="org.springframework.web.context">
> > > +               <level value="INFO" />
> > > +       </logger>
> > > +       <logger name="org.springframework.web.context.support">
> > > +               <level value="WARN" />
> > > +       </logger>
> > > +       <logger name="org.quartz">
> > > +               <level value="WARN" />
> > > +       </logger>
> > > +       <!-- Caching -->
> > > +       <logger name="net.sf.ehcache">
> > > +               <level value="INFO" />
> > > +       </logger>
> > > +       <logger name="ch.qos">
> > > +               <level value="WARN" />
> > > +       </logger>
> > > +</configuration>
> > >
> > > Modified: incubator/openmeetings/trunk/singlewebapp/build.xml
> > > URL:
> > >
> >
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/build.xml?rev=1306748&r1=1306747&r2=1306748&view=diff
> > >
> > >
> >
> ==============================================================================
> > > --- incubator/openmeetings/trunk/singlewebapp/build.xml (original)
> > > +++ incubator/openmeetings/trunk/singlewebapp/build.xml Thu Mar 29
> > > 08:14:45 2012
> > > @@ -35,7 +35,7 @@
> > >        <property name="mainlibs.lib.dir"
> > > value="${project.lib.dir}/mainlibs" />
> > >        <property name="om.lib.dir" value="${project.lib.dir}/om" />
> > >        <property name="anakia.lib.dir"
> value="${project.lib.dir}/anakia"
> > />
> > > -       <property name="red5-screenshare.images"
> > > value="${basedir}/WebContent/red5-screenshare" />
> > > +       <property name="red5-screenshare.resources"
> > > value="${basedir}/WebContent/red5-screenshare" />
> > >        <property name="junit.lib.dir" value="${project.lib.dir}/junit"
> />
> > >        <property name="rat.lib.dir" value="${project.lib.dir}/rat" />
> > >        <property name="dtd-generator.lib.dir"
> > > value="${project.lib.dir}/dtd-generator" />
> > > @@ -294,7 +294,7 @@
> > >                        <fileset dir="${main.out.dir}">
> > >                                <include name="org/red5/screen/**" />
> > >                        </fileset>
> > > -                       <fileset file="${red5.lib}/conf/logback.xml"/>
> > > +                       <fileset
> > > file="${red5-screenshare.resources}/logback.xml"/>
> > >                        <manifest>
> > >                                <attribute name="Built-By"
> > > value="OpenMeetings - http://openmeetings.googlecode.com" />
> > >                                <attribute name="Built-On"
> > > value="${build.TODAY}" />
> > > @@ -321,7 +321,7 @@
> > >                        </dname>
> > >                </genkey>
> > >                <copy todir="${screenshare.out.dir}" filtering="true">
> > > -                       <fileset dir="${red5-screenshare.images}" />
> > > +                       <fileset dir="${red5-screenshare.resources}"
> > > includes="*.jpg"/>
> > >                        <fileset dir="${red5.server.lib}"
> > > includes="commons-codec*.jar" />
> > >                        <fileset dir="${red5.server.lib}"
> > > includes="httpclient*.jar" />
> > >                        <fileset dir="${red5.server.lib}"
> > > includes="httpcore*.jar" />
> > >
> > > Modified:
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/installation/ImportInitvalues.java
> > > URL:
> > >
> >
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/installation/ImportInitvalues.java?rev=1306748&r1=1306747&r2=1306748&view=diff
> > >
> > >
> >
> ==============================================================================
> > > ---
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/installation/ImportInitvalues.java
> > > (original)
> > > +++
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/installation/ImportInitvalues.java
> > > Thu Mar 29 08:14:45 2012
> > > @@ -479,8 +479,9 @@ public class ImportInitvalues {
> > >                cfgManagement.addConfByKey(3, "show.facebook.login", ""
> +
> > > 0, null,
> > >                                "Show Facebook Login");
> > >
> > > -               cfgManagement.addConfByKey(3,
> > > "default.quality.screensharing", "0",
> > > -                               null, "Default selection in
> ScreenSharing
> > > Quality");
> > > +               cfgManagement.addConfByKey(3,
> > > "default.quality.screensharing", "1",
> > > +                                               null,
> > > +                                               "Default selection in
> > > ScreenSharing Quality:\n 0 - bigger frame rate, no resize\n 1 - no
> > resize\n
> > > 2 - size == 1/2 of selected area\n 3 - size == 3/8 of selected area");
> > >
> > >                cfgManagement.addConfByKey(3, "default.dashboard.tab",
> > "0",
> > > null,
> > >                                "Default selection in Dashboard tabs as
> > > tab-index-id");
> > >
> > > Modified:
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/CommonScreenShare.java
> > > URL:
> > >
> >
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/CommonScreenShare.java?rev=1306748&r1=1306747&r2=1306748&view=diff
> > >
> > >
> >
> ==============================================================================
> > > ---
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/CommonScreenShare.java
> > > (original)
> > > +++
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/CommonScreenShare.java
> > > Thu Mar 29 08:14:45 2012
> > > @@ -1,13 +1,11 @@
> > >  package org.red5.screen.webstart;
> > >
> > >  import java.awt.Color;
> > > -import java.awt.Graphics2D;
> > >  import java.awt.Image;
> > >  import java.awt.MouseInfo;
> > >  import java.awt.Point;
> > >  import java.awt.PointerInfo;
> > >  import java.awt.Rectangle;
> > > -import java.awt.RenderingHints;
> > >  import java.awt.Robot;
> > >  import java.awt.Toolkit;
> > >  import java.awt.datatransfer.Clipboard;
> > > @@ -22,14 +20,10 @@ import java.awt.event.KeyEvent;
> > >  import java.awt.event.WindowAdapter;
> > >  import java.awt.event.WindowEvent;
> > >  import java.awt.image.BufferedImage;
> > > -import java.awt.image.DataBuffer;
> > > -import java.io.ByteArrayOutputStream;
> > >  import java.io.IOException;
> > > -import java.io.OutputStream;
> > >  import java.util.HashMap;
> > >  import java.util.Iterator;
> > >  import java.util.Map;
> > > -import java.util.zip.DeflaterOutputStream;
> > >
> > >  import javax.imageio.ImageIO;
> > >  import javax.swing.ImageIcon;
> > > @@ -45,6 +39,7 @@ import org.red5.io.ITagWriter;
> > >  import org.red5.io.utils.ObjectMap;
> > >  import org.red5.screen.webstart.gui.VirtualScreen;
> > >  import org.red5.screen.webstart.gui.VirtualScreenBean;
> > > +import org.red5.screen.webstart.gui.VirtualScreenBean.ScreenQuality;
> > >  import org.red5.server.api.event.IEvent;
> > >  import org.red5.server.api.service.IPendingServiceCall;
> > >  import org.red5.server.net.rtmp.Channel;
> > > @@ -117,7 +112,7 @@ public class CommonScreenShare {
> > >        public String host = "btg199251";
> > >        public String app = "oflaDemo";
> > >        public int port = 1935;
> > > -       public int defaultQualityScreensharing = 0;
> > > +       public int defaultQualityScreensharing = 1;
> > >
> > >        public Long organization_id = 0L;
> > >        public Long user_id = null;
> > > @@ -157,11 +152,7 @@ public class CommonScreenShare {
> > >        public String label1092 = "Medium Quality -";
> > >        public String label1093 = "Low Quality -";
> > >
> > > -       public Float imgQuality = new Float(0.40);
> > > -
> > > -       // public Float scaleFactor = 1F;
> > > -       public float Ampl_factor = 1.3f;
> > > -
> > > +       public float Ampl_factor = 1f;
> > >        public boolean isConnected = false;
> > >
> > >        public Map<Integer, Boolean> currentPressedKeys = new
> > > HashMap<Integer, Boolean>();
> > > @@ -179,6 +170,9 @@ public class CommonScreenShare {
> > >        public void main(String[] args) {
> > >                try {
> > >                        if (args.length == 9) {
> > > +                               for (String arg : args) {
> > > +                                       logger.debug("arg: " + arg);
> > > +                               }
> > >
> > >                                host = args[0];
> > >                                app = args[1];
> > > @@ -308,13 +302,6 @@ public class CommonScreenShare {
> > >                        // *****
> > >                        // Text Recording
> > >                        textAreaHeaderRecording = new JLabel();
> > > -
> > > -                       // FIXME: Set Font to bold
> > > -                       // textAreaHeaderRecording.setB
> > > -                       // Font f = textAreaHeaderRecording.getFont();
> > > -                       //
> > > textAreaHeaderRecording.setFont(f.deriveFont(f.getStyle() ^
> > > -                       // Font.BOLD));
> > > -
> > >                        textAreaHeaderRecording.setText(this.label869);
> > >                        contentPane.add(textAreaHeaderRecording);
> > >                        textAreaHeaderRecording.setBounds(10, 340, 480,
> > 24);
> > > @@ -421,9 +408,6 @@ public class CommonScreenShare {
> > >                        PointerInfo a = MouseInfo.getPointerInfo();
> > >                        Point mouseP = a.getLocation();
> > >
> > > -                       // Integer x =
> > > Long.valueOf(Math.round(mouseP.getX())).intValue();
> > > -                       // Integer y =
> > > Long.valueOf(Math.round(mouseP.getY())).intValue();
> > > -
> > >                        Float scaleFactor =
> > > Float.valueOf(VirtualScreenBean.vScreenResizeX)
> > >                                        /
> > > Float.valueOf(VirtualScreenBean.vScreenSpinnerWidth);
> > >
> > > @@ -643,18 +627,6 @@ public class CommonScreenShare {
> > >
> > >                                // VirtualScreenBean
> > >
> > > -                               // Integer x = Math.round ( ( (
> > > -                               //
> > > Float.valueOf(returnMap.get("x").toString()).floatValue()
> > > -                               // *VirtualScreenBean.vScreenResizeX
> > > -                               //
> > > )/VirtualScreenBean.vScreenSpinnerWidth) / Ampl_factor) ;
> > > -                               // Integer y = Math.round ( ( (
> > > -                               //
> > > Float.valueOf(returnMap.get("y").toString()).floatValue()
> > > -                               // *VirtualScreenBean.vScreenResizeY
> > > -                               //
> > > )/VirtualScreenBean.vScreenSpinnerHeight)/ Ampl_factor) ;
> > > -                               //
> > > -
> > > -                               // logger.debug("x 1
> > "+returnMap.get("x"));
> > > -
> > >                                Float scaleFactor = Float
> > >
> > >  .valueOf(VirtualScreenBean.vScreenSpinnerWidth)
> > >                                                /
> > > Float.valueOf(VirtualScreenBean.vScreenResizeX);
> > > @@ -951,13 +923,10 @@ public class CommonScreenShare {
> > >                        ex.printStackTrace();
> > >                }
> > >                return "";
> > > -               // clippy.setContents( clippysContent ,null);
> > > //zur�cksetzen vom alten
> > > -               // Kontext
> > >        }
> > >
> > >        private void pressSpecialSign(String charValue, Robot instance)
> {
> > >                Clipboard clippy =
> > > Toolkit.getDefaultToolkit().getSystemClipboard();
> > > -               // Transferable clippysContent = clippy.getContents(
> null
> > > );
> > >                try {
> > >
> > >                        Transferable transferableText = new
> > > StringSelection(charValue);
> > > @@ -1042,7 +1011,7 @@ public class CommonScreenShare {
> > >                                        logger.debug("The Stream was
> > > already started ");
> > >                                }
> > >
> > > -                               if (returnMap.get("modus") != null) {
> > > +                               if (returnMap != null &&
> > > returnMap.get("modus") != null) {
> > >                                        if
> > > (returnMap.get("modus").toString()
> > >
> > >  .equals("startStreaming")) {
> > >
> > >  this.startButton.setEnabled(false);
> > > @@ -1076,12 +1045,7 @@ public class CommonScreenShare {
> > >                                logger.debug("setup capture thread
> > > vScreenSpinnerHeight "
> > >                                                +
> > > VirtualScreenBean.vScreenSpinnerHeight);
> > >
> > > -                               capture = new
> > > CaptureScreen(VirtualScreenBean.vScreenSpinnerX,
> > > -
> > > VirtualScreenBean.vScreenSpinnerY,
> > > -
> > > VirtualScreenBean.vScreenSpinnerWidth,
> > > -
> > > VirtualScreenBean.vScreenSpinnerHeight,
> > > -
> > > VirtualScreenBean.vScreenResizeX,
> > > -
> > > VirtualScreenBean.vScreenResizeY);
> > > +                               capture = new CaptureScreen();
> > >
> > >                                if (thread == null) {
> > >                                        thread = new Thread(capture);
> > > @@ -1154,11 +1118,6 @@ public class CommonScreenShare {
> > >
> > >                kt++;
> > >
> > > -               // if ( kt < 10 ) {
> > > -               // logger.debug( "+++ " + videoData );
> > > -               // System.out.println( "+++ " + videoData);
> > > -               // }
> > > -
> > >                RTMPMessage rtmpMsg = RTMPMessage.build(videoData);
> > >                instance.publishStreamData(publishStreamId, rtmpMsg);
> > >        }
> > > @@ -1170,14 +1129,6 @@ public class CommonScreenShare {
> > >        //
> > >
> ------------------------------------------------------------------------
> > >
> > >        private final class CaptureScreen extends Object implements
> > > Runnable {
> > > -               private volatile int x = 0;
> > > -               private volatile int y = 0;
> > > -               private volatile int resizeX;
> > > -               private volatile int resizeY;
> > > -
> > > -               private volatile int width = resizeX; // 320
> > > -               private volatile int height = resizeY; // 240
> > > -
> > >                private int timeBetweenFrames = 1000; // frameRate
> > >
> > >                private volatile long timestamp = 0;
> > > @@ -1185,7 +1136,7 @@ public class CommonScreenShare {
> > >                private volatile boolean active = true;
> > >                @SuppressWarnings("unused")
> > >                private volatile boolean stopped = false;
> > > -               private byte[] previousItems = null;
> > > +               private IScreenEncoder se;
> > >
> > >                //
> > >
> ------------------------------------------------------------------------
> > >                //
> > > @@ -1193,27 +1144,9 @@ public class CommonScreenShare {
> > >                //
> > >                //
> > >
> ------------------------------------------------------------------------
> > >
> > > -               public CaptureScreen(final int x, final int y, final
> int
> > > width,
> > > -                               final int height, int resizeX, int
> > > resizeY) {
> > > -
> > > -                       this.x = x;
> > > -                       this.y = y;
> > > -                       this.width = width;
> > > -                       this.height = height;
> > > -                       this.resizeX = resizeX;
> > > -                       this.resizeY = resizeY;
> > > -
> > > -                       if (VirtualScreenBean.vScreenScaleFactor
> > > -                                       .equals(label1090)) {
> > > -                               timeBetweenFrames = 100;
> > > -                       } else {
> > > -                               timeBetweenFrames = 1000;
> > > -                       }
> > > -
> > > -                       logger.debug("CaptureScreen: x=" + x + ", y="
> + y
> > > + ", w=" + width
> > > -                                       + ", h=" + height +
> ",resizeX=" +
> > > resizeX + " resizeY= "
> > > -                                       + resizeY);
> > > -
> > > +               public CaptureScreen() {
> > > +                       timeBetweenFrames =
> > > (VirtualScreenBean.screenQuality == ScreenQuality.VeryHigh) ? 100 :
> 1000;
> > > +                       se = new ScreenV1Encoder();
> > >                }
> > >
> > >                //
> > >
> ------------------------------------------------------------------------
> > > @@ -1234,7 +1167,7 @@ public class CommonScreenShare {
> > >                }
> > >
> > >                public void resetBuffer() {
> > > -                       this.previousItems = null;
> > > +                       se.reset();
> > >                }
> > >
> > >                //
> > >
> ------------------------------------------------------------------------
> > > @@ -1242,89 +1175,27 @@ public class CommonScreenShare {
> > >                // Thread loop
> > >                //
> > >                //
> > >
> ------------------------------------------------------------------------
> > > -
> > >                public void run() {
> > > -                       final int blockWidth = 32;
> > > -                       final int blockHeight = 32;
> > > -
> > > -                       int frameCounter = 0;
> > > -
> > > -                       int orig_width = width;
> > > -                       int orig_height = height;
> > > -
> > >                        try {
> > >                                Robot robot = new Robot();
> > >
> > > -                               this.previousItems = null;
> > > -
> > >                                while (active) {
> > >                                        final long ctime =
> > > System.currentTimeMillis();
> > >
> > > -                                       width = orig_width;
> > > -                                       height = orig_height;
> > > -
> > > -                                       BufferedImage image = robot
> > > -
> > > .createScreenCapture(new Rectangle(x, y, width,
> > > -
> > > height));
> > > -
> > > -                                       int width_new = resizeX;
> > > -                                       int height_new = resizeY;
> > > -                                       width = resizeX;
> > > -                                       height = resizeY;
> > > -                                       // Resize to 640*480
> > > -                                       // Create new (blank) image of
> > > required (scaled) size
> > > -                                       BufferedImage image_raw = new
> > > BufferedImage(width_new,
> > > -                                                       height_new,
> > > BufferedImage.TYPE_INT_RGB);
> > > -
> > > -                                       Graphics2D graphics2D =
> > > image_raw.createGraphics();
> > > -                                       graphics2D.setRenderingHint(
> > > -
> > > RenderingHints.KEY_INTERPOLATION,
> > > -
> > > RenderingHints.VALUE_INTERPOLATION_BICUBIC);
> > > -                                       graphics2D.drawImage(image, 0,
> 0,
> > > width_new, height_new,
> > > -                                                       null);
> > > -                                       graphics2D.dispose();
> > > -
> > > -                                       // End resize
> > > -
> > > -                                       int scaledWidth = width;
> > > -                                       int scaledHeight = height;
> > > -
> > > -                                       byte[] current =
> > toBGR(image_raw);
> > > -                                       // if (scaleFactor != 1F) {
> > > -                                       //
> > > -                                       // logger.debug("Calc new
> Scaled
> > > Instance ",scaleFactor);
> > > -                                       //
> > > -                                       // scaledWidth =
> > > -                                       //
> > > Float.valueOf(Math.round(width*scaleFactor)).intValue();
> > > -                                       // scaledHeight =
> > > -                                       //
> > > Float.valueOf(Math.round(height*scaleFactor)).intValue();
> > > -                                       //
> > > -                                       // Image img =
> > > image_raw.getScaledInstance(scaledWidth,
> > > -                                       //
> > > scaledHeight,Image.SCALE_SMOOTH);
> > > -                                       //
> > > -                                       // BufferedImage image_scaled =
> > new
> > > -                                       // BufferedImage(scaledWidth,
> > > -                                       //
> > > scaledHeight,BufferedImage.TYPE_3BYTE_BGR);
> > > -                                       //
> > > -                                       // Graphics2D biContext =
> > > image_scaled.createGraphics();
> > > -                                       // biContext.drawImage(img, 0,
> 0,
> > > null);
> > > -                                       // current =
> toBGR(image_scaled);
> > > -                                       // } else {
> > > -                                       // current = toBGR(image_raw);
> > > -                                       // }
> > > +                                       Rectangle screen = new
> > > Rectangle(VirtualScreenBean.vScreenSpinnerX,
> > > +
> > > VirtualScreenBean.vScreenSpinnerY,
> > > +
> > > VirtualScreenBean.vScreenSpinnerWidth,
> > > +
> > > VirtualScreenBean.vScreenSpinnerHeight);
> > > +
> > > +                                       BufferedImage image =
> > > robot.createScreenCapture(screen);
> > >
> > >                                        try {
> > > -                                               // timestamp +=
> (1000000
> > /
> > > timeBetweenFrames);
> > >                                                timestamp +=
> > > timeBetweenFrames;
> > >
> > > -                                               final byte[]
> screenBytes
> > =
> > > encode(current,
> > > -
> > > this.previousItems, blockWidth, blockHeight,
> > > -
> > > scaledWidth, scaledHeight);
> > > -
> > > pushVideo(screenBytes.length, screenBytes, timestamp);
> > > -                                               this.previousItems =
> > > current;
> > > +                                               byte[] data =
> > > se.encode(screen, image, new
> Rectangle(VirtualScreenBean.vScreenResizeX,
> > > +
> > > VirtualScreenBean.vScreenResizeY));
> > >
> > > -                                               if (++frameCounter %
> 100
> > > == 0)
> > > -
> > this.previousItems
> > > = null;
> > > +                                               pushVideo(data.length,
> > > data, timestamp);
> > >                                        } catch (Exception e) {
> > >                                                e.printStackTrace();
> > >                                        }
> > > @@ -1339,132 +1210,5 @@ public class CommonScreenShare {
> > >                                e.printStackTrace();
> > >                        }
> > >                }
> > > -
> > > -               //
> > >
> ------------------------------------------------------------------------
> > > -               //
> > > -               // Private
> > > -               //
> > > -               //
> > >
> ------------------------------------------------------------------------
> > > -
> > > -               private byte[] toBGR(BufferedImage image) {
> > > -                       final int width = image.getWidth();
> > > -                       final int height = image.getHeight();
> > > -
> > > -                       byte[] buf = new byte[3 * width * height];
> > > -
> > > -                       final DataBuffer buffer =
> > > image.getData().getDataBuffer();
> > > -
> > > -                       for (int y = 0; y < height; y++) {
> > > -                               for (int x = 0; x < width; x++) {
> > > -                                       final int rgb =
> buffer.getElem(y
> > *
> > > width + x);
> > > -                                       final int offset = 3 * (y *
> width
> > > + x);
> > > -
> > > -                                       buf[offset + 0] = (byte) (rgb &
> > > 0xFF);
> > > -                                       buf[offset + 1] = (byte) ((rgb
> >>
> > > 8) & 0xFF);
> > > -                                       buf[offset + 2] = (byte) ((rgb
> >>
> > > 16) & 0xFF);
> > > -                               }
> > > -                       }
> > > -
> > > -                       return buf;
> > > -               }
> > > -
> > > -               private byte[] encode(final byte[] current, final
> byte[]
> > > previous,
> > > -                               final int blockWidth, final int
> > > blockHeight, final int width,
> > > -                               final int height) throws Exception {
> > > -                       ByteArrayOutputStream baos = new
> > > ByteArrayOutputStream(16 * 1024);
> > > -
> > > -                       if (previous == null) {
> > > -                               baos.write(getTag(0x01, 0x03)); //
> > > keyframe (all cells)
> > > -                       } else {
> > > -                               baos.write(getTag(0x02, 0x03)); //
> frame
> > > (changed cells)
> > > -                       }
> > > -
> > > -                       // write header
> > > -                       final int wh = width + ((blockWidth / 16 - 1)
> <<
> > > 12);
> > > -                       final int hh = height + ((blockHeight / 16 - 1)
> > <<
> > > 12);
> > > -
> > > -                       writeShort(baos, wh);
> > > -                       writeShort(baos, hh);
> > > -
> > > -                       // write content
> > > -                       int y0 = height;
> > > -                       int x0 = 0;
> > > -                       int bwidth = blockWidth;
> > > -                       int bheight = blockHeight;
> > > -
> > > -                       while (y0 > 0) {
> > > -                               bheight = Math.min(y0, blockHeight);
> > > -                               y0 -= bheight;
> > > -
> > > -                               bwidth = blockWidth;
> > > -                               x0 = 0;
> > > -
> > > -                               while (x0 < width) {
> > > -                                       bwidth = (x0 + blockWidth >
> > width)
> > > ? width - x0
> > > -                                                       : blockWidth;
> > > -
> > > -                                       final boolean changed =
> > > isChanged(current, previous, x0,
> > > -                                                       y0, bwidth,
> > > bheight, width, height);
> > > -
> > > -                                       if (changed) {
> > > -                                               ByteArrayOutputStream
> > > blaos = new ByteArrayOutputStream(
> > > -                                                               4 *
> > 1024);
> > > -
> > > -                                               DeflaterOutputStream
> dos
> > =
> > > new DeflaterOutputStream(
> > > -                                                               blaos);
> > > -
> > > -                                               for (int y = 0; y <
> > > bheight; y++) {
> > > -
> > dos.write(current,
> > > 3 * ((y0 + bheight - y - 1)
> > > -
>   *
> > > width + x0), 3 * bwidth);
> > > -                                               }
> > > -
> > > -                                               dos.finish();
> > > -
> > > -                                               final byte[] bbuf =
> > > blaos.toByteArray();
> > > -                                               final int written =
> > > bbuf.length;
> > > -
> > > -                                               // write DataSize
> > > -                                               writeShort(baos,
> > written);
> > > -                                               // write Data
> > > -                                               baos.write(bbuf, 0,
> > > written);
> > > -                                       } else {
> > > -                                               // write DataSize
> > > -                                               writeShort(baos, 0);
> > > -                                       }
> > > -
> > > -                                       x0 += bwidth;
> > > -                               }
> > > -                       }
> > > -
> > > -                       return baos.toByteArray();
> > > -               }
> > > -
> > > -               private void writeShort(OutputStream os, final int n)
> > > throws Exception {
> > > -                       os.write((n >> 8) & 0xFF);
> > > -                       os.write((n >> 0) & 0xFF);
> > > -               }
> > > -
> > > -               public boolean isChanged(final byte[] current, final
> > > byte[] previous,
> > > -                               final int x0, final int y0, final int
> > > blockWidth,
> > > -                               final int blockHeight, final int width,
> > > final int height) {
> > > -                       if (previous == null)
> > > -                               return true;
> > > -
> > > -                       for (int y = y0, ny = y0 + blockHeight; y < ny;
> > > y++) {
> > > -                               final int foff = 3 * (x0 + width * y);
> > > -                               final int poff = 3 * (x0 + width * y);
> > > -
> > > -                               for (int i = 0, ni = 3 * blockWidth; i
> <
> > > ni; i++) {
> > > -                                       if (current[foff + i] !=
> > > previous[poff + i])
> > > -                                               return true;
> > > -                               }
> > > -                       }
> > > -
> > > -                       return false;
> > > -               }
> > > -
> > > -               public int getTag(final int frame, final int codec) {
> > > -                       return ((frame & 0x0F) << 4) + ((codec & 0x0F)
> <<
> > > 0);
> > > -               }
> > >        }
> > >  }
> > >
> > > Added:
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/IScreenEncoder.java
> > > URL:
> > >
> >
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/IScreenEncoder.java?rev=1306748&view=auto
> > >
> > >
> >
> ==============================================================================
> > > ---
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/IScreenEncoder.java
> > > (added)
> > > +++
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/IScreenEncoder.java
> > > Thu Mar 29 08:14:45 2012
> > > @@ -0,0 +1,30 @@
> > > +/*
> > > + * Licensed to the Apache Software Foundation (ASF) under one
> > > + * or more contributor license agreements.  See the NOTICE file
> > > + * distributed with this work for additional information
> > > + * regarding copyright ownership.  The ASF licenses this file
> > > + * to you under the Apache License, Version 2.0 (the
> > > + * "License") +  you may not use this file except in compliance
> > > + * with the License.  You may obtain a copy of the License at
> > > + *
> > > + *   http://www.apache.org/licenses/LICENSE-2.0
> > > + *
> > > + * Unless required by applicable law or agreed to in writing,
> > > + * software distributed under the License is distributed on an
> > > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > > + * KIND, either express or implied.  See the License for the
> > > + * specific language governing permissions and limitations
> > > + * under the License.
> > > + */
> > > +package org.red5.screen.webstart;
> > > +
> > > +import java.awt.Rectangle;
> > > +import java.awt.image.BufferedImage;
> > > +import java.io.IOException;
> > > +
> > > +public interface IScreenEncoder {
> > > +
> > > +       byte[] encode(Rectangle screen, BufferedImage img, Rectangle
> > size)
> > >  throws IOException;
> > > +
> > > +       void reset();
> > > +}
> > >
> > > Added:
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/ScreenV1Encoder.java
> > > URL:
> > >
> >
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/ScreenV1Encoder.java?rev=1306748&view=auto
> > >
> > >
> >
> ==============================================================================
> > > ---
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/ScreenV1Encoder.java
> > > (added)
> > > +++
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/ScreenV1Encoder.java
> > > Thu Mar 29 08:14:45 2012
> > > @@ -0,0 +1,146 @@
> > > +/*
> > > + * Licensed to the Apache Software Foundation (ASF) under one
> > > + * or more contributor license agreements.  See the NOTICE file
> > > + * distributed with this work for additional information
> > > + * regarding copyright ownership.  The ASF licenses this file
> > > + * to you under the Apache License, Version 2.0 (the
> > > + * "License") +  you may not use this file except in compliance
> > > + * with the License.  You may obtain a copy of the License at
> > > + *
> > > + *   http://www.apache.org/licenses/LICENSE-2.0
> > > + *
> > > + * Unless required by applicable law or agreed to in writing,
> > > + * software distributed under the License is distributed on an
> > > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > > + * KIND, either express or implied.  See the License for the
> > > + * specific language governing permissions and limitations
> > > + * under the License.
> > > + */
> > > +package org.red5.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;
> > > +
> > > +public class ScreenV1Encoder implements IScreenEncoder {
> > > +       private BufferedImage last = null;
> > > +       private static int KEY_FRAME_INDEX = 100;
> > > +       private static int DEFAULT_BLOCK_SIZE = 32;
> > > +       private int keyFrameIndex;
> > > +       private int frameCount = 0;
> > > +       private int blockSize;
> > > +       private Rectangle screen;
> > > +
> > > +       public ScreenV1Encoder() {
> > > +               this(KEY_FRAME_INDEX, DEFAULT_BLOCK_SIZE);
> > > +       }
> > > +
> > > +       //will create square blocks
> > > +       public ScreenV1Encoder(int keyFrameIndex, int blockSize) {
> > > +               this.keyFrameIndex = keyFrameIndex;
> > > +               if (blockSize < 16 || blockSize > 256 || blockSize % 16
> > !=
> > > 0) {
> > > +                       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;
> > > +       }
> > > +
> > > +       public byte[] encode(Rectangle screen, BufferedImage _img,
> > > Rectangle size) throws IOException {
> > > +               BufferedImage img = resize(_img, size);
> > > +               Rectangle imgArea = new Rectangle(img.getWidth(),
> > > img.getHeight());
> > > +               Rectangle area = getNextBlock(imgArea, null);
> > > +               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));
> > > +               writeShort(ba, imgArea.height + ((blockSize / 16 - 1)
> <<
> > > 12));
> > > +
> > > +               while (area.width > 0 && area.height > 0) {
> > > +                       writeBytesIfChanged(ba, isKeyFrame, img, area);
> > > +                       area = getNextBlock(imgArea, area);
> > > +               }
> > > +               this.screen = screen;
> > > +               last = img;
> > > +               return ba.toByteArray();
> > > +       }
> > > +
> > > +       public void reset() {
> > > +               last = null;
> > > +       }
> > > +
> > > +       private Rectangle getNextBlock(Rectangle img, Rectangle _prev)
> {
> > > +               Rectangle prev;
> > > +               if (_prev == null) {
> > > +                       prev = new Rectangle(0, Math.max(0, img.height
> -
> > > blockSize), blockSize, blockSize);
> > > +               } else {
> > > +                       prev = new Rectangle(_prev);
> > > +                       if (prev.x + prev.width == img.getWidth()) {
> > > +                               if (prev.y == 0) return new
> Rectangle();
> > > //the end of the image
> > > +                               //next row
> > > +                               prev.x = 0; //reset position
> > > +                               prev.width = blockSize; //reset width
> > > +                               prev.y -= (prev.y > blockSize ?
> blockSize
> > > : prev.y);
> > > +                       } else {
> > > +                               prev.x += blockSize;
> > > +                       }
> > > +               }
> > > +               return img.intersection(prev);
> > > +       }
> > > +
> > > +       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);
> > > +               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
> > > +                               });
> > > +                       }
> > > +               }
> > > +               dos.finish();
> > > +               if (changed) {
> > > +                       final int written = baos.size();
> > > +                       writeShort(ba, written);
> > > +                       ba.write(baos.toByteArray(), 0, written);
> > > +               } else {
> > > +                       writeShort(ba, 0);
> > > +               }
> > > +       }
> > > +
> > > +       public int getTag(final int frame, final int codec) {
> > > +               return ((frame & 0x0F) << 4) + ((codec & 0x0F) << 0);
> > > +       }
> > > +
> > > +       private void writeShort(OutputStream os, final int n) throws
> > > IOException {
> > > +               os.write((n >> 8) & 0xFF);
> > > +               os.write((n >> 0) & 0xFF);
> > > +       }
> > > +}
> > >
> > > Modified:
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreen.java
> > > URL:
> > >
> >
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreen.java?rev=1306748&r1=1306747&r2=1306748&view=diff
> > >
> > >
> >
> ==============================================================================
> > > ---
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreen.java
> > > (original)
> > > +++
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreen.java
> > > Thu Mar 29 08:14:45 2012
> > > @@ -18,27 +18,29 @@
> > >  */
> > >  package org.red5.screen.webstart.gui;
> > >
> > > -import javax.imageio.ImageIO;
> > >  import java.awt.Color;
> > >  import java.awt.Dimension;
> > >  import java.awt.Image;
> > >  import java.awt.Rectangle;
> > >  import java.awt.Robot;
> > > +import java.awt.event.ActionEvent;
> > > +import java.awt.event.ActionListener;
> > >  import java.awt.image.BufferedImage;
> > >
> > > -import javax.swing.SwingConstants;
> > > +import javax.imageio.ImageIO;
> > >  import javax.swing.ImageIcon;
> > > -import javax.swing.JLabel;
> > >  import javax.swing.JComboBox;
> > > +import javax.swing.JLabel;
> > >  import javax.swing.JSpinner;
> > >  import javax.swing.SpinnerNumberModel;
> > > +import javax.swing.SwingConstants;
> > >  import javax.swing.event.ChangeEvent;
> > >  import javax.swing.event.ChangeListener;
> > > -import java.awt.event.*;
> > >
> > >  import org.red5.screen.webstart.BlankArea;
> > >  import org.red5.screen.webstart.CommonScreenShare;
> > >  import org.red5.screen.webstart.ScreenShare;
> > > +import org.red5.screen.webstart.gui.VirtualScreenBean.ScreenQuality;
> > >  import org.slf4j.Logger;
> > >  import org.slf4j.LoggerFactory;
> > >
> > > @@ -50,6 +52,40 @@ public class VirtualScreen {
> > >
> > >        public boolean doUpdateBounds = true;
> > >
> > > +       private class KeyValue<T> {
> > > +               private String key;
> > > +               private T value;
> > > +
> > > +               public KeyValue(String key, T value) {
> > > +                       this.key = key;
> > > +                       this.value = value;
> > > +               }
> > > +
> > > +               @SuppressWarnings("unused")
> > > +               public String getKey() { return key; }
> > > +               public T getValue() { return value; }
> > > +
> > > +               @Override
> > > +               public String toString() { return key; }
> > > +
> > > +               @Override
> > > +               public boolean equals(Object obj) {
> > > +                       if (obj instanceof KeyValue) {
> > > +                               @SuppressWarnings("unchecked")
> > > +                               KeyValue<T> kv = (KeyValue<T>) obj;
> > > +                               return (kv.value.equals(this.value));
> > > +                       }
> > > +                       return false;
> > > +               }
> > > +
> > > +               @Override
> > > +               public int hashCode() {
> > > +                       int hash = 7;
> > > +                       hash = 97 * hash + (this.value != null ?
> > > this.value.hashCode() : 0);
> > > +                       return hash;
> > > +               }
> > > +       }
> > > +
> > >        public VirtualScreen(CommonScreenShare css) throws Exception {
> > >                this.css = css;
> > >
> > > @@ -175,7 +211,6 @@ public class VirtualScreen {
> > >                css.jVScreenXSpin.setBounds(400, 170, 60, 24);
> > >                css.jVScreenXSpin.addChangeListener( new
> ChangeListener(){
> > >                        public void stateChanged(ChangeEvent arg0) {
> > > -                               // TODO Auto-generated method stub
> > >                                calcNewValueXSpin();
> > >                        }
> > >                });
> > > @@ -194,7 +229,6 @@ public class VirtualScreen {
> > >                css.jVScreenYSpin.setBounds(400, 200, 60, 24);
> > >                css.jVScreenYSpin.addChangeListener( new
> ChangeListener(){
> > >                        public void stateChanged(ChangeEvent arg0) {
> > > -                               // TODO Auto-generated method stub
> > >                                calcNewValueYSpin();
> > >                        }
> > >                });
> > > @@ -213,7 +247,6 @@ public class VirtualScreen {
> > >                css.jVScreenWidthSpin.setBounds(400, 240, 60, 24);
> > >                css.jVScreenWidthSpin.addChangeListener( new
> > > ChangeListener(){
> > >                        public void stateChanged(ChangeEvent arg0) {
> > > -                               // TODO Auto-generated method stub
> > >                                calcNewValueWidthSpin();
> > >                        }
> > >                });
> > > @@ -232,15 +265,12 @@ public class VirtualScreen {
> > >                css.jVScreenHeightSpin.setBounds(400, 270, 60, 24);
> > >                css.jVScreenHeightSpin.addChangeListener( new
> > > ChangeListener(){
> > >                        public void stateChanged(ChangeEvent arg0) {
> > > -                               // TODO Auto-generated method stub
> > >                                calcNewValueHeightSpin();
> > >                        }
> > >                });
> > >                css.t.add(css.jVScreenHeightSpin);
> > >
> > >
> > > -               //String[] selectResize = { css.label1090,
> css.label1091,
> > > css.label1092, css.label1093 };
> > > -               String[] selectResize = { css.label1091, css.label1092,
> > > css.label1093 };
> > >                VirtualScreenBean.vScreenResizeX = 640;
> > >                VirtualScreenBean.vScreenResizeY = 400;
> > >
> > > @@ -249,84 +279,55 @@ public class VirtualScreen {
> > >                css.vscreenResizeLabel.setBounds(250, 300, 200,24 );
> > >                css.t.add(css.vscreenResizeLabel);
> > >
> > > -               JComboBox comboResize  = new JComboBox(selectResize);
> > > +               JComboBox comboResize  = new JComboBox();
> > > +               comboResize.addItem(new
> > > KeyValue<ScreenQuality>(css.label1090, ScreenQuality.VeryHigh));
> > > +               comboResize.addItem(new
> > > KeyValue<ScreenQuality>(css.label1091, ScreenQuality.High));
> > > +               comboResize.addItem(new
> > > KeyValue<ScreenQuality>(css.label1092, ScreenQuality.Medium));
> > > +               comboResize.addItem(new
> > > KeyValue<ScreenQuality>(css.label1093, ScreenQuality.Low));
> > >                comboResize.setBounds(250, 330, 200, 24);
> > > -               comboResize.addActionListener(new GetResizeChoice());
> > > +               comboResize.addActionListener(new ActionListener(){
> > > +                       @SuppressWarnings("unchecked")
> > > +                       public void actionPerformed(ActionEvent e) {
> > > +                               JComboBox cb =
> (JComboBox)e.getSource();
> > > +                       VirtualScreenBean.screenQuality =
> > > ((KeyValue<ScreenQuality>)cb.getSelectedItem()).getValue();
> > > +                       calcRescaleFactors();
> > > +                       }
> > > +               });
> > >
> > >  comboResize.setSelectedIndex(css.defaultQualityScreensharing);
> > >
> > >                css.jVScreenResizeMode = comboResize;
> > >                css.t.add(css.jVScreenResizeMode);
> > >
> > >        }
> > > -       class GetResizeChoice implements ActionListener
> > > -       {
> > > -               public void actionPerformed (ActionEvent e)
> > > -               {
> > > -
> > > -                       JComboBox cb = (JComboBox)e.getSource();
> > > -               String petName = (String)cb.getSelectedItem();
> > > -
> > > -               VirtualScreenBean.vScreenScaleFactor = petName;
> > > -
> > > -               calcRescaleFactors();
> > > -
> > > -               }
> > > -       }
> > >
> > >        /**
> > >         * Needs to be always invoked after every re-scaling
> > >         */
> > >        void calcRescaleFactors() {
> > > -
> > >                logger.debug("calcRescaleFactors -- ");
> > > -
> > > if(VirtualScreenBean.vScreenScaleFactor.equals(css.label1090))
> > > -        {
> > > -                       logger.debug("resize:
> > >
> >
> X:"+Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue()+
> > > -                                       "
> > >
> >
> Y:"+Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue());
> > > -
> > > -                       VirtualScreenBean.vScreenResizeX =
> > >
> Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue();
> > > -                       VirtualScreenBean.vScreenResizeY =
> > >
> Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue();
> > > -                       updateVScreenBounds();
> > > -        }
> > > -               else
> > > if(VirtualScreenBean.vScreenScaleFactor.equals(css.label1091))
> > > -        {
> > > -               logger.debug("resize:
> > >
> >
> X:"+Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue()+
> > > -                                                       "
> > >
> >
> Y:"+Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue());
> > > -
> > > -               VirtualScreenBean.vScreenResizeX =
> > >
> Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue();
> > > -               VirtualScreenBean.vScreenResizeY =
> > >
> Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue();
> > > -               updateVScreenBounds();
> > > -        }
> > > -        else
> > > if(VirtualScreenBean.vScreenScaleFactor.equals(css.label1092))
> > > -        {
> > > -               logger.debug("resize:
> > >
> >
> X:"+Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue()/2+
> > > -                                                       "
> > >
> >
> Y:"+Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue()/2);
> > > -
> > > -               VirtualScreenBean.vScreenResizeX =
> > >
> >
> (Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue())/2;
> > > -               VirtualScreenBean.vScreenResizeY =
> > >
> >
> (Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue())/2;
> > > -               updateVScreenBounds();
> > > -        }
> > > -        else
> > > if(VirtualScreenBean.vScreenScaleFactor.equals(css.label1093))
> > > -        {
> > > -               logger.debug("resize:
> > >
> >
> X:"+(Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue()/8)*3+
> > > -                                                       "
> > >
> >
> Y:"+(Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue()/8)*3);
> > > -
> > > -               VirtualScreenBean.vScreenResizeX =
> > >
> >
> (Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue()/8)*3;
> > > -               VirtualScreenBean.vScreenResizeY =
> > >
> >
> (Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue()/8)*3;
> > > -               updateVScreenBounds();
> > > -        }
> > > -
> > > -                logger.debug("########## calcRescaleFactors
> > > vScreenResizeX " + VirtualScreenBean.vScreenResizeX);
> > > -         logger.debug("########## calcRescaleFactors vScreenResizeY "
> +
> > > VirtualScreenBean.vScreenResizeY);
> > > -         logger.debug("########## calcRescaleFactors
> vScreenScaleFactor
> > "
> > > + VirtualScreenBean.vScreenScaleFactor);
> > > -
> > > +               VirtualScreenBean.vScreenResizeX =
> > >
> Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue();
> > > +               VirtualScreenBean.vScreenResizeY =
> > >
> Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue();
> > > +               switch (VirtualScreenBean.screenQuality) {
> > > +                       case VeryHigh:
> > > +                       case High:
> > > +                               break;
> > > +                       case Medium:
> > > +                               VirtualScreenBean.vScreenResizeX *=
> 1/2;
> > > +                               VirtualScreenBean.vScreenResizeY *= 2;
> > > +                               break;
> > > +                       case Low:
> > > +                               VirtualScreenBean.vScreenResizeX *=
> 3/8;
> > > +                               VirtualScreenBean.vScreenResizeY *=
> 3/8;
> > > +                               break;
> > > +               }
> > > +               logger.debug("resize: X:" +
> > > VirtualScreenBean.vScreenResizeX + " Y: " +
> > > VirtualScreenBean.vScreenResizeY);
> > > +               updateVScreenBounds();
> > >        }
> > >
> > >        void calcNewValueXSpin(){
> > >                if (this.doUpdateBounds){
> > >                        int newX =
> > > Integer.valueOf(css.jVScreenXSpin.getValue().toString()).intValue();
> > >                        if(VirtualScreenBean.vScreenSpinnerWidth+newX >
> > > VirtualScreenBean.screenWidthMax){
> > > -//                             System.out.println("WARNING X
> > > "+VirtualScreenBean.vScreenSpinnerWidth+" "+newX);
> > >
> > >
> >
>  newX=VirtualScreenBean.screenWidthMax-VirtualScreenBean.vScreenSpinnerWidth;
> > >                                css.jVScreenXSpin.setValue(newX);
> > >                                if (this.showWarning)
> > > css.showBandwidthWarning("Reduce the width of the SharingScreen before
> > you
> > > try to move it left");
> > > @@ -363,7 +364,6 @@ public class VirtualScreen {
> > >                if (this.doUpdateBounds){
> > >                        int newWidth =
> > >
> Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue();
> > >                        if(VirtualScreenBean.vScreenSpinnerX+newWidth >
> > > VirtualScreenBean.screenWidthMax){
> > > -//                             System.out.println("WARNING WIDTH");
> > >
> > >
> >
>  newWidth=VirtualScreenBean.screenWidthMax-VirtualScreenBean.vScreenSpinnerX;
> > >
>  css.jVScreenWidthSpin.setValue(newWidth);
> > >                                if
> > > (this.showWarning)css.showBandwidthWarning("Reduce the x of the
> > > SharingScreen before you try to make it wider");
> > >
> > > Modified:
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreenBean.java
> > > URL:
> > >
> >
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreenBean.java?rev=1306748&r1=1306747&r2=1306748&view=diff
> > >
> > >
> >
> ==============================================================================
> > > ---
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreenBean.java
> > > (original)
> > > +++
> > >
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreenBean.java
> > > Thu Mar 29 08:14:45 2012
> > > @@ -18,11 +18,8 @@
> > >  */
> > >  package org.red5.screen.webstart.gui;
> > >
> > > -import java.awt.Robot;
> > >
> > >  public class VirtualScreenBean {
> > > -
> > > -
> > >        /**
> > >         * image recalcing value's from the virtual Screen drawer
> > >         */
> > > @@ -47,13 +44,15 @@ public class VirtualScreenBean {
> > >        public static int vScreenSpinnerX = 0;
> > >        public static int vScreenSpinnerY = 0;
> > >
> > > -       public static String vScreenScaleFactor = "Medium Quality";
> > > +       public static ScreenQuality screenQuality =
> ScreenQuality.Medium;
> > >
> > >        public static int vScreenResizeX = 480;
> > >        public static int vScreenResizeY = 360;
> > >
> > > -
> > > -       public static Robot robot = null;
> > > -
> > > -       public static Float imgQuality = new Float(0.40);
> > > +       public enum ScreenQuality {
> > > +               VeryHigh
> > > +               , High
> > > +               , Medium
> > > +               , Low
> > > +       }
> > >  }
> > >
> > >
> > >
> >
> >
> > --
> > Sebastian Wagner
> > https://twitter.com/#!/dead_lock
> > http://www.openmeetings.de <http://incubator.apache.org/openmeetings/>
> > http://www.webbase-design.de
> > http://www.wagner-sebastian.com
> > seba.wagner@gmail.com
> >
>
>
>
> --
> WBR
> Maxim aka solomax
>



-- 
Sebastian Wagner
https://twitter.com/#!/dead_lock
http://www.openmeetings.de <http://incubator.apache.org/openmeetings/>
http://www.webbase-design.de
http://www.wagner-sebastian.com
seba.wagner@gmail.com

Re: svn commit: r1306748 - in /incubator/openmeetings/trunk/singlewebapp: ./ WebContent/red5-screenshare/ src/org/openmeetings/app/installation/ src/org/red5/screen/webstart/ src/org/red5/screen/webstart/gui/

Posted by Maxim Solodovnik <so...@gmail.com>.
I was able to find _some_ of spec necessary. And was able to "guess"
missing parts (1 page of documentation is too few)

I'll check Medium and Low quality and rename package + modify the build

I have changed  1.3 to be 1.0 (no need for upscale IMHO).

regarding copy/paste:
1) I don't really like the idea of "static VirtualScreenBean" (it is not
bean, there is no need to make it static)
2) various methods contains lots of similar code:
      a) VirtualScreen.updateVScreenBounds() similar calculations with lots
of casting
      b) CommonScreenShare.sendRemoteCursorEvent similar blocks of code
3) I don't really like how the code is organized (I'm not 'comfortable'
with it maybe will review it in a spare time)

On Fri, Mar 30, 2012 at 00:11, seba.wagner@gmail.com
<se...@gmail.com>wrote:

> Hi Maxim,
>
> nice job :) Have you find something in the Specs for the protocol?
>
> Btw: Sharing or recording with medium or low quality throws some exception
> now:
> java.lang.IllegalArgumentException: Width (0) and height (2048) cannot be
> <= 0
>    at
> java.awt.image.DirectColorModel.createCompatibleWritableRaster(Unknown
> Source)
>    at java.awt.image.BufferedImage.<init>(Unknown Source)
>    at
> org.red5.screen.webstart.ScreenV1Encoder.resize(ScreenV1Encoder.java:55)
>    at
> org.red5.screen.webstart.ScreenV1Encoder.encode(ScreenV1Encoder.java:68)
>    at
>
> org.red5.screen.webstart.CommonScreenShare$CaptureScreen.run(CommonScreenShare.java:1195)
>    at java.lang.Thread.run(Unknown Source)
>
> About the quality settings in the client: Did you also change the "normal"
> (high) quality that it does _not_ rescale the screen anymore? Previously
> the factor was 1.3 for the normal modus. I don't think that this is
> neccessary.
>
> I think we should also fix the the package name to fit into our structure,
> what do you think?
>
> What did you mean by *The code still need to be reviewed to remove
> copy/pasted code* ?
>
> Thanks!
> Sebastian
>
>
> 2012/3/29 <so...@apache.org>
>
> > Author: solomax
> > Date: Thu Mar 29 08:14:45 2012
> > New Revision: 1306748
> >
> > URL: http://svn.apache.org/viewvc?rev=1306748&view=rev
> > Log:
> > Screen sharing client cleaned up from 'borrowed' code; code cleanup
> >
> > Added:
> >
> >
>  incubator/openmeetings/trunk/singlewebapp/WebContent/red5-screenshare/logback.xml
> >
> >
>  incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/IScreenEncoder.java
> >
> >
>  incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/ScreenV1Encoder.java
> > Modified:
> >    incubator/openmeetings/trunk/singlewebapp/build.xml
> >
> >
>  incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/installation/ImportInitvalues.java
> >
> >
>  incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/CommonScreenShare.java
> >
> >
>  incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreen.java
> >
> >
>  incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreenBean.java
> >
> > Added:
> >
> incubator/openmeetings/trunk/singlewebapp/WebContent/red5-screenshare/logback.xml
> > URL:
> >
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/WebContent/red5-screenshare/logback.xml?rev=1306748&view=auto
> >
> >
> ==============================================================================
> > ---
> >
> incubator/openmeetings/trunk/singlewebapp/WebContent/red5-screenshare/logback.xml
> > (added)
> > +++
> >
> incubator/openmeetings/trunk/singlewebapp/WebContent/red5-screenshare/logback.xml
> > Thu Mar 29 08:14:45 2012
> > @@ -0,0 +1,159 @@
> > +<?xml version="1.0" encoding="UTF-8"?>
> > +<configuration>
> > +       <!-- Uncomment if you are using the logback plugin for eclipse
> > +       <consolePlugin/>
> > +       -->
> > +       <appender name="CONSOLE"
> > class="ch.qos.logback.core.ConsoleAppender">
> > +               <encoder>
> > +                       <pattern>[%p] [%thread] %logger -
> %msg%n</pattern>
> > +               </encoder>
> > +       </appender>
> > +       <root>
> > +               <level value="WARN" />
> > +               <appender-ref ref="CONSOLE" />
> > +       </root>
> > +       <!-- Red5 -->
> > +       <logger name="org.red5.server.Launcher">
> > +               <level value="INFO" />
> > +       </logger>
> > +       <logger name="org.red5.io">
> > +               <level value="INFO" />
> > +       </logger>
> > +    <logger name="org.red5.logging.DerbyLogInterceptor">
> > +        <level value="WARN" />
> > +    </logger>
> > +    <logger name="org.red5.server">
> > +        <level value="WARN" />
> > +    </logger>
> > +       <logger name="org.red5.server.Client">
> > +               <level value="INFO" />
> > +       </logger>
> > +       <logger name="org.red5.server.api.stream.support">
> > +               <level value="INFO" />
> > +       </logger>
> > +       <logger name="org.red5.server.cache">
> > +               <level value="WARN" />
> > +       </logger>
> > +       <logger name="org.red5.server.jmx">
> > +               <level value="WARN" />
> > +       </logger>
> > +       <logger name="org.red5.server.messaging.InMemoryPushPushPipe">
> > +               <level value="INFO" />
> > +       </logger>
> > +       <logger name="org.red5.server.net">
> > +               <level value="INFO" />
> > +       </logger>
> > +       <logger name="org.red5.server.net.rtmpt.RTMPTServlet">
> > +               <level value="WARN" />
> > +       </logger>
> > +       <logger name="org.red5.server.net.servlet">
> > +               <level value="WARN" />
> > +       </logger>
> > +       <logger name="org.red5.server.net.proxy">
> > +               <level value="INFO" />
> > +       </logger>
> > +       <logger name="org.red5.server.net.remoting">
> > +               <level value="WARN" />
> > +       </logger>
> > +       <logger name="org.red5.server.net.rtmp">
> > +               <level value="WARN" />
> > +       </logger>
> > +       <logger name="org.red5.server.net.rtmp.BaseRTMPHandler">
> > +               <level value="WARN" />
> > +       </logger>
> > +       <logger name="org.red5.server.net.rtmp.RTMPMinaIoHandler">
> > +               <level value="WARN" />
> > +       </logger>
> > +       <logger name="org.red5.server.net.rtmp.status">
> > +               <level value="INFO" />
> > +       </logger>
> > +       <logger name="org.red5.server.net.rtmpt">
> > +               <level value="WARN" />
> > +       </logger>
> > +       <logger name="org.red5.server.persistence">
> > +               <level value="WARN" />
> > +       </logger>
> > +       <logger name="org.red5.server.script">
> > +               <level value="WARN" />
> > +       </logger>
> > +       <logger name="org.red5.server.service">
> > +               <level value="INFO" />
> > +       </logger>
> > +       <logger name="org.red5.server.so">
> > +               <level value="WARN" />
> > +       </logger>
> > +       <logger name="org.red5.server.stream">
> > +               <level value="INFO" />
> > +       </logger>
> > +       <logger name="org.red5.server.stream.consumer">
> > +               <level value="WARN" />
> > +       </logger>
> > +       <logger name="org.red5.server.net.mrtmp">
> > +               <level value="WARN" />
> > +       </logger>
> > +       <!-- Mina -->
> > +       <logger name="org.apache.mina">
> > +               <level value="WARN" />
> > +       </logger>
> > +       <logger name="org.apache.mina.filter">
> > +               <level value="WARN" />
> > +       </logger>
> > +       <logger
> > name="org.red5.server.adapter.MultiThreadedApplicationAdapter" >
> > +               <level value="INFO"/>
> > +       </logger>
> > +       <!-- Apache commons -->
> > +       <logger name="org.apache.commons">
> > +               <level value="WARN" />
> > +       </logger>
> > +       <logger name="httpclient">
> > +               <level value="WARN" />
> > +       </logger>
> > +       <!-- Apache catalina / tomcat -->
> > +    <logger name="org.red5.server.tomcat">
> > +        <level value="INFO" />
> > +    </logger>
> > +    <logger name="org.apache.catalina">
> > +        <level value="WARN" />
> > +    </logger>
> > +       <logger name="org.apache.jasper">
> > +               <level value="INFO" />
> > +       </logger>
> > +       <logger name="org.apache.tomcat">
> > +               <level value="INFO" />
> > +       </logger>
> > +       <logger name="org.apache.tomcat.util.net">
> > +               <level value="WARN" />
> > +       </logger>
> > +       <logger name="org.apache.coyote.http11">
> > +               <level value="INFO" />
> > +       </logger>
> > +       <!-- Spring -->
> > +       <logger name="org.springframework">
> > +               <level value="INFO" />
> > +       </logger>
> > +       <logger name="org.springframework.beans.factory">
> > +               <level value="INFO" />
> > +       </logger>
> > +       <logger name="org.springframework.beans.factory.xml">
> > +               <level value="WARN" />
> > +       </logger>
> > +       <logger name="org.springframework.ui.context.support">
> > +               <level value="WARN" />
> > +       </logger>
> > +       <logger name="org.springframework.web.context">
> > +               <level value="INFO" />
> > +       </logger>
> > +       <logger name="org.springframework.web.context.support">
> > +               <level value="WARN" />
> > +       </logger>
> > +       <logger name="org.quartz">
> > +               <level value="WARN" />
> > +       </logger>
> > +       <!-- Caching -->
> > +       <logger name="net.sf.ehcache">
> > +               <level value="INFO" />
> > +       </logger>
> > +       <logger name="ch.qos">
> > +               <level value="WARN" />
> > +       </logger>
> > +</configuration>
> >
> > Modified: incubator/openmeetings/trunk/singlewebapp/build.xml
> > URL:
> >
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/build.xml?rev=1306748&r1=1306747&r2=1306748&view=diff
> >
> >
> ==============================================================================
> > --- incubator/openmeetings/trunk/singlewebapp/build.xml (original)
> > +++ incubator/openmeetings/trunk/singlewebapp/build.xml Thu Mar 29
> > 08:14:45 2012
> > @@ -35,7 +35,7 @@
> >        <property name="mainlibs.lib.dir"
> > value="${project.lib.dir}/mainlibs" />
> >        <property name="om.lib.dir" value="${project.lib.dir}/om" />
> >        <property name="anakia.lib.dir" value="${project.lib.dir}/anakia"
> />
> > -       <property name="red5-screenshare.images"
> > value="${basedir}/WebContent/red5-screenshare" />
> > +       <property name="red5-screenshare.resources"
> > value="${basedir}/WebContent/red5-screenshare" />
> >        <property name="junit.lib.dir" value="${project.lib.dir}/junit" />
> >        <property name="rat.lib.dir" value="${project.lib.dir}/rat" />
> >        <property name="dtd-generator.lib.dir"
> > value="${project.lib.dir}/dtd-generator" />
> > @@ -294,7 +294,7 @@
> >                        <fileset dir="${main.out.dir}">
> >                                <include name="org/red5/screen/**" />
> >                        </fileset>
> > -                       <fileset file="${red5.lib}/conf/logback.xml"/>
> > +                       <fileset
> > file="${red5-screenshare.resources}/logback.xml"/>
> >                        <manifest>
> >                                <attribute name="Built-By"
> > value="OpenMeetings - http://openmeetings.googlecode.com" />
> >                                <attribute name="Built-On"
> > value="${build.TODAY}" />
> > @@ -321,7 +321,7 @@
> >                        </dname>
> >                </genkey>
> >                <copy todir="${screenshare.out.dir}" filtering="true">
> > -                       <fileset dir="${red5-screenshare.images}" />
> > +                       <fileset dir="${red5-screenshare.resources}"
> > includes="*.jpg"/>
> >                        <fileset dir="${red5.server.lib}"
> > includes="commons-codec*.jar" />
> >                        <fileset dir="${red5.server.lib}"
> > includes="httpclient*.jar" />
> >                        <fileset dir="${red5.server.lib}"
> > includes="httpcore*.jar" />
> >
> > Modified:
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/installation/ImportInitvalues.java
> > URL:
> >
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/installation/ImportInitvalues.java?rev=1306748&r1=1306747&r2=1306748&view=diff
> >
> >
> ==============================================================================
> > ---
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/installation/ImportInitvalues.java
> > (original)
> > +++
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/installation/ImportInitvalues.java
> > Thu Mar 29 08:14:45 2012
> > @@ -479,8 +479,9 @@ public class ImportInitvalues {
> >                cfgManagement.addConfByKey(3, "show.facebook.login", "" +
> > 0, null,
> >                                "Show Facebook Login");
> >
> > -               cfgManagement.addConfByKey(3,
> > "default.quality.screensharing", "0",
> > -                               null, "Default selection in ScreenSharing
> > Quality");
> > +               cfgManagement.addConfByKey(3,
> > "default.quality.screensharing", "1",
> > +                                               null,
> > +                                               "Default selection in
> > ScreenSharing Quality:\n 0 - bigger frame rate, no resize\n 1 - no
> resize\n
> > 2 - size == 1/2 of selected area\n 3 - size == 3/8 of selected area");
> >
> >                cfgManagement.addConfByKey(3, "default.dashboard.tab",
> "0",
> > null,
> >                                "Default selection in Dashboard tabs as
> > tab-index-id");
> >
> > Modified:
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/CommonScreenShare.java
> > URL:
> >
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/CommonScreenShare.java?rev=1306748&r1=1306747&r2=1306748&view=diff
> >
> >
> ==============================================================================
> > ---
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/CommonScreenShare.java
> > (original)
> > +++
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/CommonScreenShare.java
> > Thu Mar 29 08:14:45 2012
> > @@ -1,13 +1,11 @@
> >  package org.red5.screen.webstart;
> >
> >  import java.awt.Color;
> > -import java.awt.Graphics2D;
> >  import java.awt.Image;
> >  import java.awt.MouseInfo;
> >  import java.awt.Point;
> >  import java.awt.PointerInfo;
> >  import java.awt.Rectangle;
> > -import java.awt.RenderingHints;
> >  import java.awt.Robot;
> >  import java.awt.Toolkit;
> >  import java.awt.datatransfer.Clipboard;
> > @@ -22,14 +20,10 @@ import java.awt.event.KeyEvent;
> >  import java.awt.event.WindowAdapter;
> >  import java.awt.event.WindowEvent;
> >  import java.awt.image.BufferedImage;
> > -import java.awt.image.DataBuffer;
> > -import java.io.ByteArrayOutputStream;
> >  import java.io.IOException;
> > -import java.io.OutputStream;
> >  import java.util.HashMap;
> >  import java.util.Iterator;
> >  import java.util.Map;
> > -import java.util.zip.DeflaterOutputStream;
> >
> >  import javax.imageio.ImageIO;
> >  import javax.swing.ImageIcon;
> > @@ -45,6 +39,7 @@ import org.red5.io.ITagWriter;
> >  import org.red5.io.utils.ObjectMap;
> >  import org.red5.screen.webstart.gui.VirtualScreen;
> >  import org.red5.screen.webstart.gui.VirtualScreenBean;
> > +import org.red5.screen.webstart.gui.VirtualScreenBean.ScreenQuality;
> >  import org.red5.server.api.event.IEvent;
> >  import org.red5.server.api.service.IPendingServiceCall;
> >  import org.red5.server.net.rtmp.Channel;
> > @@ -117,7 +112,7 @@ public class CommonScreenShare {
> >        public String host = "btg199251";
> >        public String app = "oflaDemo";
> >        public int port = 1935;
> > -       public int defaultQualityScreensharing = 0;
> > +       public int defaultQualityScreensharing = 1;
> >
> >        public Long organization_id = 0L;
> >        public Long user_id = null;
> > @@ -157,11 +152,7 @@ public class CommonScreenShare {
> >        public String label1092 = "Medium Quality -";
> >        public String label1093 = "Low Quality -";
> >
> > -       public Float imgQuality = new Float(0.40);
> > -
> > -       // public Float scaleFactor = 1F;
> > -       public float Ampl_factor = 1.3f;
> > -
> > +       public float Ampl_factor = 1f;
> >        public boolean isConnected = false;
> >
> >        public Map<Integer, Boolean> currentPressedKeys = new
> > HashMap<Integer, Boolean>();
> > @@ -179,6 +170,9 @@ public class CommonScreenShare {
> >        public void main(String[] args) {
> >                try {
> >                        if (args.length == 9) {
> > +                               for (String arg : args) {
> > +                                       logger.debug("arg: " + arg);
> > +                               }
> >
> >                                host = args[0];
> >                                app = args[1];
> > @@ -308,13 +302,6 @@ public class CommonScreenShare {
> >                        // *****
> >                        // Text Recording
> >                        textAreaHeaderRecording = new JLabel();
> > -
> > -                       // FIXME: Set Font to bold
> > -                       // textAreaHeaderRecording.setB
> > -                       // Font f = textAreaHeaderRecording.getFont();
> > -                       //
> > textAreaHeaderRecording.setFont(f.deriveFont(f.getStyle() ^
> > -                       // Font.BOLD));
> > -
> >                        textAreaHeaderRecording.setText(this.label869);
> >                        contentPane.add(textAreaHeaderRecording);
> >                        textAreaHeaderRecording.setBounds(10, 340, 480,
> 24);
> > @@ -421,9 +408,6 @@ public class CommonScreenShare {
> >                        PointerInfo a = MouseInfo.getPointerInfo();
> >                        Point mouseP = a.getLocation();
> >
> > -                       // Integer x =
> > Long.valueOf(Math.round(mouseP.getX())).intValue();
> > -                       // Integer y =
> > Long.valueOf(Math.round(mouseP.getY())).intValue();
> > -
> >                        Float scaleFactor =
> > Float.valueOf(VirtualScreenBean.vScreenResizeX)
> >                                        /
> > Float.valueOf(VirtualScreenBean.vScreenSpinnerWidth);
> >
> > @@ -643,18 +627,6 @@ public class CommonScreenShare {
> >
> >                                // VirtualScreenBean
> >
> > -                               // Integer x = Math.round ( ( (
> > -                               //
> > Float.valueOf(returnMap.get("x").toString()).floatValue()
> > -                               // *VirtualScreenBean.vScreenResizeX
> > -                               //
> > )/VirtualScreenBean.vScreenSpinnerWidth) / Ampl_factor) ;
> > -                               // Integer y = Math.round ( ( (
> > -                               //
> > Float.valueOf(returnMap.get("y").toString()).floatValue()
> > -                               // *VirtualScreenBean.vScreenResizeY
> > -                               //
> > )/VirtualScreenBean.vScreenSpinnerHeight)/ Ampl_factor) ;
> > -                               //
> > -
> > -                               // logger.debug("x 1
> "+returnMap.get("x"));
> > -
> >                                Float scaleFactor = Float
> >
> >  .valueOf(VirtualScreenBean.vScreenSpinnerWidth)
> >                                                /
> > Float.valueOf(VirtualScreenBean.vScreenResizeX);
> > @@ -951,13 +923,10 @@ public class CommonScreenShare {
> >                        ex.printStackTrace();
> >                }
> >                return "";
> > -               // clippy.setContents( clippysContent ,null);
> > //zur�cksetzen vom alten
> > -               // Kontext
> >        }
> >
> >        private void pressSpecialSign(String charValue, Robot instance) {
> >                Clipboard clippy =
> > Toolkit.getDefaultToolkit().getSystemClipboard();
> > -               // Transferable clippysContent = clippy.getContents( null
> > );
> >                try {
> >
> >                        Transferable transferableText = new
> > StringSelection(charValue);
> > @@ -1042,7 +1011,7 @@ public class CommonScreenShare {
> >                                        logger.debug("The Stream was
> > already started ");
> >                                }
> >
> > -                               if (returnMap.get("modus") != null) {
> > +                               if (returnMap != null &&
> > returnMap.get("modus") != null) {
> >                                        if
> > (returnMap.get("modus").toString()
> >
> >  .equals("startStreaming")) {
> >
> >  this.startButton.setEnabled(false);
> > @@ -1076,12 +1045,7 @@ public class CommonScreenShare {
> >                                logger.debug("setup capture thread
> > vScreenSpinnerHeight "
> >                                                +
> > VirtualScreenBean.vScreenSpinnerHeight);
> >
> > -                               capture = new
> > CaptureScreen(VirtualScreenBean.vScreenSpinnerX,
> > -
> > VirtualScreenBean.vScreenSpinnerY,
> > -
> > VirtualScreenBean.vScreenSpinnerWidth,
> > -
> > VirtualScreenBean.vScreenSpinnerHeight,
> > -
> > VirtualScreenBean.vScreenResizeX,
> > -
> > VirtualScreenBean.vScreenResizeY);
> > +                               capture = new CaptureScreen();
> >
> >                                if (thread == null) {
> >                                        thread = new Thread(capture);
> > @@ -1154,11 +1118,6 @@ public class CommonScreenShare {
> >
> >                kt++;
> >
> > -               // if ( kt < 10 ) {
> > -               // logger.debug( "+++ " + videoData );
> > -               // System.out.println( "+++ " + videoData);
> > -               // }
> > -
> >                RTMPMessage rtmpMsg = RTMPMessage.build(videoData);
> >                instance.publishStreamData(publishStreamId, rtmpMsg);
> >        }
> > @@ -1170,14 +1129,6 @@ public class CommonScreenShare {
> >        //
> > ------------------------------------------------------------------------
> >
> >        private final class CaptureScreen extends Object implements
> > Runnable {
> > -               private volatile int x = 0;
> > -               private volatile int y = 0;
> > -               private volatile int resizeX;
> > -               private volatile int resizeY;
> > -
> > -               private volatile int width = resizeX; // 320
> > -               private volatile int height = resizeY; // 240
> > -
> >                private int timeBetweenFrames = 1000; // frameRate
> >
> >                private volatile long timestamp = 0;
> > @@ -1185,7 +1136,7 @@ public class CommonScreenShare {
> >                private volatile boolean active = true;
> >                @SuppressWarnings("unused")
> >                private volatile boolean stopped = false;
> > -               private byte[] previousItems = null;
> > +               private IScreenEncoder se;
> >
> >                //
> > ------------------------------------------------------------------------
> >                //
> > @@ -1193,27 +1144,9 @@ public class CommonScreenShare {
> >                //
> >                //
> > ------------------------------------------------------------------------
> >
> > -               public CaptureScreen(final int x, final int y, final int
> > width,
> > -                               final int height, int resizeX, int
> > resizeY) {
> > -
> > -                       this.x = x;
> > -                       this.y = y;
> > -                       this.width = width;
> > -                       this.height = height;
> > -                       this.resizeX = resizeX;
> > -                       this.resizeY = resizeY;
> > -
> > -                       if (VirtualScreenBean.vScreenScaleFactor
> > -                                       .equals(label1090)) {
> > -                               timeBetweenFrames = 100;
> > -                       } else {
> > -                               timeBetweenFrames = 1000;
> > -                       }
> > -
> > -                       logger.debug("CaptureScreen: x=" + x + ", y=" + y
> > + ", w=" + width
> > -                                       + ", h=" + height + ",resizeX=" +
> > resizeX + " resizeY= "
> > -                                       + resizeY);
> > -
> > +               public CaptureScreen() {
> > +                       timeBetweenFrames =
> > (VirtualScreenBean.screenQuality == ScreenQuality.VeryHigh) ? 100 : 1000;
> > +                       se = new ScreenV1Encoder();
> >                }
> >
> >                //
> > ------------------------------------------------------------------------
> > @@ -1234,7 +1167,7 @@ public class CommonScreenShare {
> >                }
> >
> >                public void resetBuffer() {
> > -                       this.previousItems = null;
> > +                       se.reset();
> >                }
> >
> >                //
> > ------------------------------------------------------------------------
> > @@ -1242,89 +1175,27 @@ public class CommonScreenShare {
> >                // Thread loop
> >                //
> >                //
> > ------------------------------------------------------------------------
> > -
> >                public void run() {
> > -                       final int blockWidth = 32;
> > -                       final int blockHeight = 32;
> > -
> > -                       int frameCounter = 0;
> > -
> > -                       int orig_width = width;
> > -                       int orig_height = height;
> > -
> >                        try {
> >                                Robot robot = new Robot();
> >
> > -                               this.previousItems = null;
> > -
> >                                while (active) {
> >                                        final long ctime =
> > System.currentTimeMillis();
> >
> > -                                       width = orig_width;
> > -                                       height = orig_height;
> > -
> > -                                       BufferedImage image = robot
> > -
> > .createScreenCapture(new Rectangle(x, y, width,
> > -
> > height));
> > -
> > -                                       int width_new = resizeX;
> > -                                       int height_new = resizeY;
> > -                                       width = resizeX;
> > -                                       height = resizeY;
> > -                                       // Resize to 640*480
> > -                                       // Create new (blank) image of
> > required (scaled) size
> > -                                       BufferedImage image_raw = new
> > BufferedImage(width_new,
> > -                                                       height_new,
> > BufferedImage.TYPE_INT_RGB);
> > -
> > -                                       Graphics2D graphics2D =
> > image_raw.createGraphics();
> > -                                       graphics2D.setRenderingHint(
> > -
> > RenderingHints.KEY_INTERPOLATION,
> > -
> > RenderingHints.VALUE_INTERPOLATION_BICUBIC);
> > -                                       graphics2D.drawImage(image, 0, 0,
> > width_new, height_new,
> > -                                                       null);
> > -                                       graphics2D.dispose();
> > -
> > -                                       // End resize
> > -
> > -                                       int scaledWidth = width;
> > -                                       int scaledHeight = height;
> > -
> > -                                       byte[] current =
> toBGR(image_raw);
> > -                                       // if (scaleFactor != 1F) {
> > -                                       //
> > -                                       // logger.debug("Calc new Scaled
> > Instance ",scaleFactor);
> > -                                       //
> > -                                       // scaledWidth =
> > -                                       //
> > Float.valueOf(Math.round(width*scaleFactor)).intValue();
> > -                                       // scaledHeight =
> > -                                       //
> > Float.valueOf(Math.round(height*scaleFactor)).intValue();
> > -                                       //
> > -                                       // Image img =
> > image_raw.getScaledInstance(scaledWidth,
> > -                                       //
> > scaledHeight,Image.SCALE_SMOOTH);
> > -                                       //
> > -                                       // BufferedImage image_scaled =
> new
> > -                                       // BufferedImage(scaledWidth,
> > -                                       //
> > scaledHeight,BufferedImage.TYPE_3BYTE_BGR);
> > -                                       //
> > -                                       // Graphics2D biContext =
> > image_scaled.createGraphics();
> > -                                       // biContext.drawImage(img, 0, 0,
> > null);
> > -                                       // current = toBGR(image_scaled);
> > -                                       // } else {
> > -                                       // current = toBGR(image_raw);
> > -                                       // }
> > +                                       Rectangle screen = new
> > Rectangle(VirtualScreenBean.vScreenSpinnerX,
> > +
> > VirtualScreenBean.vScreenSpinnerY,
> > +
> > VirtualScreenBean.vScreenSpinnerWidth,
> > +
> > VirtualScreenBean.vScreenSpinnerHeight);
> > +
> > +                                       BufferedImage image =
> > robot.createScreenCapture(screen);
> >
> >                                        try {
> > -                                               // timestamp += (1000000
> /
> > timeBetweenFrames);
> >                                                timestamp +=
> > timeBetweenFrames;
> >
> > -                                               final byte[] screenBytes
> =
> > encode(current,
> > -
> > this.previousItems, blockWidth, blockHeight,
> > -
> > scaledWidth, scaledHeight);
> > -
> > pushVideo(screenBytes.length, screenBytes, timestamp);
> > -                                               this.previousItems =
> > current;
> > +                                               byte[] data =
> > se.encode(screen, image, new Rectangle(VirtualScreenBean.vScreenResizeX,
> > +
> > VirtualScreenBean.vScreenResizeY));
> >
> > -                                               if (++frameCounter % 100
> > == 0)
> > -
> this.previousItems
> > = null;
> > +                                               pushVideo(data.length,
> > data, timestamp);
> >                                        } catch (Exception e) {
> >                                                e.printStackTrace();
> >                                        }
> > @@ -1339,132 +1210,5 @@ public class CommonScreenShare {
> >                                e.printStackTrace();
> >                        }
> >                }
> > -
> > -               //
> > ------------------------------------------------------------------------
> > -               //
> > -               // Private
> > -               //
> > -               //
> > ------------------------------------------------------------------------
> > -
> > -               private byte[] toBGR(BufferedImage image) {
> > -                       final int width = image.getWidth();
> > -                       final int height = image.getHeight();
> > -
> > -                       byte[] buf = new byte[3 * width * height];
> > -
> > -                       final DataBuffer buffer =
> > image.getData().getDataBuffer();
> > -
> > -                       for (int y = 0; y < height; y++) {
> > -                               for (int x = 0; x < width; x++) {
> > -                                       final int rgb = buffer.getElem(y
> *
> > width + x);
> > -                                       final int offset = 3 * (y * width
> > + x);
> > -
> > -                                       buf[offset + 0] = (byte) (rgb &
> > 0xFF);
> > -                                       buf[offset + 1] = (byte) ((rgb >>
> > 8) & 0xFF);
> > -                                       buf[offset + 2] = (byte) ((rgb >>
> > 16) & 0xFF);
> > -                               }
> > -                       }
> > -
> > -                       return buf;
> > -               }
> > -
> > -               private byte[] encode(final byte[] current, final byte[]
> > previous,
> > -                               final int blockWidth, final int
> > blockHeight, final int width,
> > -                               final int height) throws Exception {
> > -                       ByteArrayOutputStream baos = new
> > ByteArrayOutputStream(16 * 1024);
> > -
> > -                       if (previous == null) {
> > -                               baos.write(getTag(0x01, 0x03)); //
> > keyframe (all cells)
> > -                       } else {
> > -                               baos.write(getTag(0x02, 0x03)); // frame
> > (changed cells)
> > -                       }
> > -
> > -                       // write header
> > -                       final int wh = width + ((blockWidth / 16 - 1) <<
> > 12);
> > -                       final int hh = height + ((blockHeight / 16 - 1)
> <<
> > 12);
> > -
> > -                       writeShort(baos, wh);
> > -                       writeShort(baos, hh);
> > -
> > -                       // write content
> > -                       int y0 = height;
> > -                       int x0 = 0;
> > -                       int bwidth = blockWidth;
> > -                       int bheight = blockHeight;
> > -
> > -                       while (y0 > 0) {
> > -                               bheight = Math.min(y0, blockHeight);
> > -                               y0 -= bheight;
> > -
> > -                               bwidth = blockWidth;
> > -                               x0 = 0;
> > -
> > -                               while (x0 < width) {
> > -                                       bwidth = (x0 + blockWidth >
> width)
> > ? width - x0
> > -                                                       : blockWidth;
> > -
> > -                                       final boolean changed =
> > isChanged(current, previous, x0,
> > -                                                       y0, bwidth,
> > bheight, width, height);
> > -
> > -                                       if (changed) {
> > -                                               ByteArrayOutputStream
> > blaos = new ByteArrayOutputStream(
> > -                                                               4 *
> 1024);
> > -
> > -                                               DeflaterOutputStream dos
> =
> > new DeflaterOutputStream(
> > -                                                               blaos);
> > -
> > -                                               for (int y = 0; y <
> > bheight; y++) {
> > -
> dos.write(current,
> > 3 * ((y0 + bheight - y - 1)
> > -                                                                       *
> > width + x0), 3 * bwidth);
> > -                                               }
> > -
> > -                                               dos.finish();
> > -
> > -                                               final byte[] bbuf =
> > blaos.toByteArray();
> > -                                               final int written =
> > bbuf.length;
> > -
> > -                                               // write DataSize
> > -                                               writeShort(baos,
> written);
> > -                                               // write Data
> > -                                               baos.write(bbuf, 0,
> > written);
> > -                                       } else {
> > -                                               // write DataSize
> > -                                               writeShort(baos, 0);
> > -                                       }
> > -
> > -                                       x0 += bwidth;
> > -                               }
> > -                       }
> > -
> > -                       return baos.toByteArray();
> > -               }
> > -
> > -               private void writeShort(OutputStream os, final int n)
> > throws Exception {
> > -                       os.write((n >> 8) & 0xFF);
> > -                       os.write((n >> 0) & 0xFF);
> > -               }
> > -
> > -               public boolean isChanged(final byte[] current, final
> > byte[] previous,
> > -                               final int x0, final int y0, final int
> > blockWidth,
> > -                               final int blockHeight, final int width,
> > final int height) {
> > -                       if (previous == null)
> > -                               return true;
> > -
> > -                       for (int y = y0, ny = y0 + blockHeight; y < ny;
> > y++) {
> > -                               final int foff = 3 * (x0 + width * y);
> > -                               final int poff = 3 * (x0 + width * y);
> > -
> > -                               for (int i = 0, ni = 3 * blockWidth; i <
> > ni; i++) {
> > -                                       if (current[foff + i] !=
> > previous[poff + i])
> > -                                               return true;
> > -                               }
> > -                       }
> > -
> > -                       return false;
> > -               }
> > -
> > -               public int getTag(final int frame, final int codec) {
> > -                       return ((frame & 0x0F) << 4) + ((codec & 0x0F) <<
> > 0);
> > -               }
> >        }
> >  }
> >
> > Added:
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/IScreenEncoder.java
> > URL:
> >
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/IScreenEncoder.java?rev=1306748&view=auto
> >
> >
> ==============================================================================
> > ---
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/IScreenEncoder.java
> > (added)
> > +++
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/IScreenEncoder.java
> > Thu Mar 29 08:14:45 2012
> > @@ -0,0 +1,30 @@
> > +/*
> > + * Licensed to the Apache Software Foundation (ASF) under one
> > + * or more contributor license agreements.  See the NOTICE file
> > + * distributed with this work for additional information
> > + * regarding copyright ownership.  The ASF licenses this file
> > + * to you under the Apache License, Version 2.0 (the
> > + * "License") +  you may not use this file except in compliance
> > + * with the License.  You may obtain a copy of the License at
> > + *
> > + *   http://www.apache.org/licenses/LICENSE-2.0
> > + *
> > + * Unless required by applicable law or agreed to in writing,
> > + * software distributed under the License is distributed on an
> > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > + * KIND, either express or implied.  See the License for the
> > + * specific language governing permissions and limitations
> > + * under the License.
> > + */
> > +package org.red5.screen.webstart;
> > +
> > +import java.awt.Rectangle;
> > +import java.awt.image.BufferedImage;
> > +import java.io.IOException;
> > +
> > +public interface IScreenEncoder {
> > +
> > +       byte[] encode(Rectangle screen, BufferedImage img, Rectangle
> size)
> >  throws IOException;
> > +
> > +       void reset();
> > +}
> >
> > Added:
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/ScreenV1Encoder.java
> > URL:
> >
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/ScreenV1Encoder.java?rev=1306748&view=auto
> >
> >
> ==============================================================================
> > ---
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/ScreenV1Encoder.java
> > (added)
> > +++
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/ScreenV1Encoder.java
> > Thu Mar 29 08:14:45 2012
> > @@ -0,0 +1,146 @@
> > +/*
> > + * Licensed to the Apache Software Foundation (ASF) under one
> > + * or more contributor license agreements.  See the NOTICE file
> > + * distributed with this work for additional information
> > + * regarding copyright ownership.  The ASF licenses this file
> > + * to you under the Apache License, Version 2.0 (the
> > + * "License") +  you may not use this file except in compliance
> > + * with the License.  You may obtain a copy of the License at
> > + *
> > + *   http://www.apache.org/licenses/LICENSE-2.0
> > + *
> > + * Unless required by applicable law or agreed to in writing,
> > + * software distributed under the License is distributed on an
> > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > + * KIND, either express or implied.  See the License for the
> > + * specific language governing permissions and limitations
> > + * under the License.
> > + */
> > +package org.red5.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;
> > +
> > +public class ScreenV1Encoder implements IScreenEncoder {
> > +       private BufferedImage last = null;
> > +       private static int KEY_FRAME_INDEX = 100;
> > +       private static int DEFAULT_BLOCK_SIZE = 32;
> > +       private int keyFrameIndex;
> > +       private int frameCount = 0;
> > +       private int blockSize;
> > +       private Rectangle screen;
> > +
> > +       public ScreenV1Encoder() {
> > +               this(KEY_FRAME_INDEX, DEFAULT_BLOCK_SIZE);
> > +       }
> > +
> > +       //will create square blocks
> > +       public ScreenV1Encoder(int keyFrameIndex, int blockSize) {
> > +               this.keyFrameIndex = keyFrameIndex;
> > +               if (blockSize < 16 || blockSize > 256 || blockSize % 16
> !=
> > 0) {
> > +                       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;
> > +       }
> > +
> > +       public byte[] encode(Rectangle screen, BufferedImage _img,
> > Rectangle size) throws IOException {
> > +               BufferedImage img = resize(_img, size);
> > +               Rectangle imgArea = new Rectangle(img.getWidth(),
> > img.getHeight());
> > +               Rectangle area = getNextBlock(imgArea, null);
> > +               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));
> > +               writeShort(ba, imgArea.height + ((blockSize / 16 - 1) <<
> > 12));
> > +
> > +               while (area.width > 0 && area.height > 0) {
> > +                       writeBytesIfChanged(ba, isKeyFrame, img, area);
> > +                       area = getNextBlock(imgArea, area);
> > +               }
> > +               this.screen = screen;
> > +               last = img;
> > +               return ba.toByteArray();
> > +       }
> > +
> > +       public void reset() {
> > +               last = null;
> > +       }
> > +
> > +       private Rectangle getNextBlock(Rectangle img, Rectangle _prev) {
> > +               Rectangle prev;
> > +               if (_prev == null) {
> > +                       prev = new Rectangle(0, Math.max(0, img.height -
> > blockSize), blockSize, blockSize);
> > +               } else {
> > +                       prev = new Rectangle(_prev);
> > +                       if (prev.x + prev.width == img.getWidth()) {
> > +                               if (prev.y == 0) return new Rectangle();
> > //the end of the image
> > +                               //next row
> > +                               prev.x = 0; //reset position
> > +                               prev.width = blockSize; //reset width
> > +                               prev.y -= (prev.y > blockSize ? blockSize
> > : prev.y);
> > +                       } else {
> > +                               prev.x += blockSize;
> > +                       }
> > +               }
> > +               return img.intersection(prev);
> > +       }
> > +
> > +       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);
> > +               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
> > +                               });
> > +                       }
> > +               }
> > +               dos.finish();
> > +               if (changed) {
> > +                       final int written = baos.size();
> > +                       writeShort(ba, written);
> > +                       ba.write(baos.toByteArray(), 0, written);
> > +               } else {
> > +                       writeShort(ba, 0);
> > +               }
> > +       }
> > +
> > +       public int getTag(final int frame, final int codec) {
> > +               return ((frame & 0x0F) << 4) + ((codec & 0x0F) << 0);
> > +       }
> > +
> > +       private void writeShort(OutputStream os, final int n) throws
> > IOException {
> > +               os.write((n >> 8) & 0xFF);
> > +               os.write((n >> 0) & 0xFF);
> > +       }
> > +}
> >
> > Modified:
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreen.java
> > URL:
> >
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreen.java?rev=1306748&r1=1306747&r2=1306748&view=diff
> >
> >
> ==============================================================================
> > ---
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreen.java
> > (original)
> > +++
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreen.java
> > Thu Mar 29 08:14:45 2012
> > @@ -18,27 +18,29 @@
> >  */
> >  package org.red5.screen.webstart.gui;
> >
> > -import javax.imageio.ImageIO;
> >  import java.awt.Color;
> >  import java.awt.Dimension;
> >  import java.awt.Image;
> >  import java.awt.Rectangle;
> >  import java.awt.Robot;
> > +import java.awt.event.ActionEvent;
> > +import java.awt.event.ActionListener;
> >  import java.awt.image.BufferedImage;
> >
> > -import javax.swing.SwingConstants;
> > +import javax.imageio.ImageIO;
> >  import javax.swing.ImageIcon;
> > -import javax.swing.JLabel;
> >  import javax.swing.JComboBox;
> > +import javax.swing.JLabel;
> >  import javax.swing.JSpinner;
> >  import javax.swing.SpinnerNumberModel;
> > +import javax.swing.SwingConstants;
> >  import javax.swing.event.ChangeEvent;
> >  import javax.swing.event.ChangeListener;
> > -import java.awt.event.*;
> >
> >  import org.red5.screen.webstart.BlankArea;
> >  import org.red5.screen.webstart.CommonScreenShare;
> >  import org.red5.screen.webstart.ScreenShare;
> > +import org.red5.screen.webstart.gui.VirtualScreenBean.ScreenQuality;
> >  import org.slf4j.Logger;
> >  import org.slf4j.LoggerFactory;
> >
> > @@ -50,6 +52,40 @@ public class VirtualScreen {
> >
> >        public boolean doUpdateBounds = true;
> >
> > +       private class KeyValue<T> {
> > +               private String key;
> > +               private T value;
> > +
> > +               public KeyValue(String key, T value) {
> > +                       this.key = key;
> > +                       this.value = value;
> > +               }
> > +
> > +               @SuppressWarnings("unused")
> > +               public String getKey() { return key; }
> > +               public T getValue() { return value; }
> > +
> > +               @Override
> > +               public String toString() { return key; }
> > +
> > +               @Override
> > +               public boolean equals(Object obj) {
> > +                       if (obj instanceof KeyValue) {
> > +                               @SuppressWarnings("unchecked")
> > +                               KeyValue<T> kv = (KeyValue<T>) obj;
> > +                               return (kv.value.equals(this.value));
> > +                       }
> > +                       return false;
> > +               }
> > +
> > +               @Override
> > +               public int hashCode() {
> > +                       int hash = 7;
> > +                       hash = 97 * hash + (this.value != null ?
> > this.value.hashCode() : 0);
> > +                       return hash;
> > +               }
> > +       }
> > +
> >        public VirtualScreen(CommonScreenShare css) throws Exception {
> >                this.css = css;
> >
> > @@ -175,7 +211,6 @@ public class VirtualScreen {
> >                css.jVScreenXSpin.setBounds(400, 170, 60, 24);
> >                css.jVScreenXSpin.addChangeListener( new ChangeListener(){
> >                        public void stateChanged(ChangeEvent arg0) {
> > -                               // TODO Auto-generated method stub
> >                                calcNewValueXSpin();
> >                        }
> >                });
> > @@ -194,7 +229,6 @@ public class VirtualScreen {
> >                css.jVScreenYSpin.setBounds(400, 200, 60, 24);
> >                css.jVScreenYSpin.addChangeListener( new ChangeListener(){
> >                        public void stateChanged(ChangeEvent arg0) {
> > -                               // TODO Auto-generated method stub
> >                                calcNewValueYSpin();
> >                        }
> >                });
> > @@ -213,7 +247,6 @@ public class VirtualScreen {
> >                css.jVScreenWidthSpin.setBounds(400, 240, 60, 24);
> >                css.jVScreenWidthSpin.addChangeListener( new
> > ChangeListener(){
> >                        public void stateChanged(ChangeEvent arg0) {
> > -                               // TODO Auto-generated method stub
> >                                calcNewValueWidthSpin();
> >                        }
> >                });
> > @@ -232,15 +265,12 @@ public class VirtualScreen {
> >                css.jVScreenHeightSpin.setBounds(400, 270, 60, 24);
> >                css.jVScreenHeightSpin.addChangeListener( new
> > ChangeListener(){
> >                        public void stateChanged(ChangeEvent arg0) {
> > -                               // TODO Auto-generated method stub
> >                                calcNewValueHeightSpin();
> >                        }
> >                });
> >                css.t.add(css.jVScreenHeightSpin);
> >
> >
> > -               //String[] selectResize = { css.label1090, css.label1091,
> > css.label1092, css.label1093 };
> > -               String[] selectResize = { css.label1091, css.label1092,
> > css.label1093 };
> >                VirtualScreenBean.vScreenResizeX = 640;
> >                VirtualScreenBean.vScreenResizeY = 400;
> >
> > @@ -249,84 +279,55 @@ public class VirtualScreen {
> >                css.vscreenResizeLabel.setBounds(250, 300, 200,24 );
> >                css.t.add(css.vscreenResizeLabel);
> >
> > -               JComboBox comboResize  = new JComboBox(selectResize);
> > +               JComboBox comboResize  = new JComboBox();
> > +               comboResize.addItem(new
> > KeyValue<ScreenQuality>(css.label1090, ScreenQuality.VeryHigh));
> > +               comboResize.addItem(new
> > KeyValue<ScreenQuality>(css.label1091, ScreenQuality.High));
> > +               comboResize.addItem(new
> > KeyValue<ScreenQuality>(css.label1092, ScreenQuality.Medium));
> > +               comboResize.addItem(new
> > KeyValue<ScreenQuality>(css.label1093, ScreenQuality.Low));
> >                comboResize.setBounds(250, 330, 200, 24);
> > -               comboResize.addActionListener(new GetResizeChoice());
> > +               comboResize.addActionListener(new ActionListener(){
> > +                       @SuppressWarnings("unchecked")
> > +                       public void actionPerformed(ActionEvent e) {
> > +                               JComboBox cb = (JComboBox)e.getSource();
> > +                       VirtualScreenBean.screenQuality =
> > ((KeyValue<ScreenQuality>)cb.getSelectedItem()).getValue();
> > +                       calcRescaleFactors();
> > +                       }
> > +               });
> >
> >  comboResize.setSelectedIndex(css.defaultQualityScreensharing);
> >
> >                css.jVScreenResizeMode = comboResize;
> >                css.t.add(css.jVScreenResizeMode);
> >
> >        }
> > -       class GetResizeChoice implements ActionListener
> > -       {
> > -               public void actionPerformed (ActionEvent e)
> > -               {
> > -
> > -                       JComboBox cb = (JComboBox)e.getSource();
> > -               String petName = (String)cb.getSelectedItem();
> > -
> > -               VirtualScreenBean.vScreenScaleFactor = petName;
> > -
> > -               calcRescaleFactors();
> > -
> > -               }
> > -       }
> >
> >        /**
> >         * Needs to be always invoked after every re-scaling
> >         */
> >        void calcRescaleFactors() {
> > -
> >                logger.debug("calcRescaleFactors -- ");
> > -
> > if(VirtualScreenBean.vScreenScaleFactor.equals(css.label1090))
> > -        {
> > -                       logger.debug("resize:
> >
> X:"+Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue()+
> > -                                       "
> >
> Y:"+Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue());
> > -
> > -                       VirtualScreenBean.vScreenResizeX =
> > Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue();
> > -                       VirtualScreenBean.vScreenResizeY =
> > Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue();
> > -                       updateVScreenBounds();
> > -        }
> > -               else
> > if(VirtualScreenBean.vScreenScaleFactor.equals(css.label1091))
> > -        {
> > -               logger.debug("resize:
> >
> X:"+Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue()+
> > -                                                       "
> >
> Y:"+Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue());
> > -
> > -               VirtualScreenBean.vScreenResizeX =
> > Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue();
> > -               VirtualScreenBean.vScreenResizeY =
> > Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue();
> > -               updateVScreenBounds();
> > -        }
> > -        else
> > if(VirtualScreenBean.vScreenScaleFactor.equals(css.label1092))
> > -        {
> > -               logger.debug("resize:
> >
> X:"+Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue()/2+
> > -                                                       "
> >
> Y:"+Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue()/2);
> > -
> > -               VirtualScreenBean.vScreenResizeX =
> >
> (Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue())/2;
> > -               VirtualScreenBean.vScreenResizeY =
> >
> (Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue())/2;
> > -               updateVScreenBounds();
> > -        }
> > -        else
> > if(VirtualScreenBean.vScreenScaleFactor.equals(css.label1093))
> > -        {
> > -               logger.debug("resize:
> >
> X:"+(Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue()/8)*3+
> > -                                                       "
> >
> Y:"+(Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue()/8)*3);
> > -
> > -               VirtualScreenBean.vScreenResizeX =
> >
> (Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue()/8)*3;
> > -               VirtualScreenBean.vScreenResizeY =
> >
> (Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue()/8)*3;
> > -               updateVScreenBounds();
> > -        }
> > -
> > -                logger.debug("########## calcRescaleFactors
> > vScreenResizeX " + VirtualScreenBean.vScreenResizeX);
> > -         logger.debug("########## calcRescaleFactors vScreenResizeY " +
> > VirtualScreenBean.vScreenResizeY);
> > -         logger.debug("########## calcRescaleFactors vScreenScaleFactor
> "
> > + VirtualScreenBean.vScreenScaleFactor);
> > -
> > +               VirtualScreenBean.vScreenResizeX =
> > Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue();
> > +               VirtualScreenBean.vScreenResizeY =
> > Integer.valueOf(css.jVScreenHeightSpin.getValue().toString()).intValue();
> > +               switch (VirtualScreenBean.screenQuality) {
> > +                       case VeryHigh:
> > +                       case High:
> > +                               break;
> > +                       case Medium:
> > +                               VirtualScreenBean.vScreenResizeX *= 1/2;
> > +                               VirtualScreenBean.vScreenResizeY *= 2;
> > +                               break;
> > +                       case Low:
> > +                               VirtualScreenBean.vScreenResizeX *= 3/8;
> > +                               VirtualScreenBean.vScreenResizeY *= 3/8;
> > +                               break;
> > +               }
> > +               logger.debug("resize: X:" +
> > VirtualScreenBean.vScreenResizeX + " Y: " +
> > VirtualScreenBean.vScreenResizeY);
> > +               updateVScreenBounds();
> >        }
> >
> >        void calcNewValueXSpin(){
> >                if (this.doUpdateBounds){
> >                        int newX =
> > Integer.valueOf(css.jVScreenXSpin.getValue().toString()).intValue();
> >                        if(VirtualScreenBean.vScreenSpinnerWidth+newX >
> > VirtualScreenBean.screenWidthMax){
> > -//                             System.out.println("WARNING X
> > "+VirtualScreenBean.vScreenSpinnerWidth+" "+newX);
> >
> >
>  newX=VirtualScreenBean.screenWidthMax-VirtualScreenBean.vScreenSpinnerWidth;
> >                                css.jVScreenXSpin.setValue(newX);
> >                                if (this.showWarning)
> > css.showBandwidthWarning("Reduce the width of the SharingScreen before
> you
> > try to move it left");
> > @@ -363,7 +364,6 @@ public class VirtualScreen {
> >                if (this.doUpdateBounds){
> >                        int newWidth =
> > Integer.valueOf(css.jVScreenWidthSpin.getValue().toString()).intValue();
> >                        if(VirtualScreenBean.vScreenSpinnerX+newWidth >
> > VirtualScreenBean.screenWidthMax){
> > -//                             System.out.println("WARNING WIDTH");
> >
> >
>  newWidth=VirtualScreenBean.screenWidthMax-VirtualScreenBean.vScreenSpinnerX;
> >                                css.jVScreenWidthSpin.setValue(newWidth);
> >                                if
> > (this.showWarning)css.showBandwidthWarning("Reduce the x of the
> > SharingScreen before you try to make it wider");
> >
> > Modified:
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreenBean.java
> > URL:
> >
> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreenBean.java?rev=1306748&r1=1306747&r2=1306748&view=diff
> >
> >
> ==============================================================================
> > ---
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreenBean.java
> > (original)
> > +++
> >
> incubator/openmeetings/trunk/singlewebapp/src/org/red5/screen/webstart/gui/VirtualScreenBean.java
> > Thu Mar 29 08:14:45 2012
> > @@ -18,11 +18,8 @@
> >  */
> >  package org.red5.screen.webstart.gui;
> >
> > -import java.awt.Robot;
> >
> >  public class VirtualScreenBean {
> > -
> > -
> >        /**
> >         * image recalcing value's from the virtual Screen drawer
> >         */
> > @@ -47,13 +44,15 @@ public class VirtualScreenBean {
> >        public static int vScreenSpinnerX = 0;
> >        public static int vScreenSpinnerY = 0;
> >
> > -       public static String vScreenScaleFactor = "Medium Quality";
> > +       public static ScreenQuality screenQuality = ScreenQuality.Medium;
> >
> >        public static int vScreenResizeX = 480;
> >        public static int vScreenResizeY = 360;
> >
> > -
> > -       public static Robot robot = null;
> > -
> > -       public static Float imgQuality = new Float(0.40);
> > +       public enum ScreenQuality {
> > +               VeryHigh
> > +               , High
> > +               , Medium
> > +               , Low
> > +       }
> >  }
> >
> >
> >
>
>
> --
> Sebastian Wagner
> https://twitter.com/#!/dead_lock
> http://www.openmeetings.de <http://incubator.apache.org/openmeetings/>
> http://www.webbase-design.de
> http://www.wagner-sebastian.com
> seba.wagner@gmail.com
>



-- 
WBR
Maxim aka solomax