Implemented variable playback speed, adjustable using a text field.


git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@2513 3789f03b-4d11-0410-bbf8-ca57d06f2519
diff --git a/java/src/com/tightvnc/rfbplayer/ButtonPanel.java b/java/src/com/tightvnc/rfbplayer/ButtonPanel.java
index 7a1e888..222c519 100644
--- a/java/src/com/tightvnc/rfbplayer/ButtonPanel.java
+++ b/java/src/com/tightvnc/rfbplayer/ButtonPanel.java
@@ -48,8 +48,6 @@
     add(new Label(" Speed:"));
     timeScaleText = new TextField(5);
     timeScaleText.setText("1.0");
-    timeScaleText.setEnabled(false);
-    timeScaleText.setEditable(false);
     add(timeScaleText);
     timeScaleText.addActionListener(this);
   }
@@ -88,6 +86,8 @@
       player.setPaused(playButton.getLabel().equals("Pause"));
     } else if (evt.getSource() == posText) {
       player.setPos(Integer.parseInt(posText.getText()));
+    } else if (evt.getSource() == timeScaleText) {
+      player.setSpeed(Double.parseDouble(timeScaleText.getText()));
     }
   }
 }
diff --git a/java/src/com/tightvnc/rfbplayer/FbsInputStream.java b/java/src/com/tightvnc/rfbplayer/FbsInputStream.java
index d47953a..7baa145 100644
--- a/java/src/com/tightvnc/rfbplayer/FbsInputStream.java
+++ b/java/src/com/tightvnc/rfbplayer/FbsInputStream.java
@@ -30,6 +30,7 @@
   protected long timeOffset;
   protected long seekOffset;
   protected boolean paused;
+  protected double playbackSpeed;
 
   protected byte[] buffer;
   protected int bufferSize;
@@ -54,6 +55,7 @@
     timeOffset = 0;
     seekOffset = -1;
     paused = false;
+    playbackSpeed = 1.0;
 
     byte[] b = new byte[12];
     readFully(b);
@@ -101,6 +103,7 @@
     timeOffset = 0;
     seekOffset = -1;
     paused = false;
+    playbackSpeed = 1.0;
 
     buffer = null;
     bufferSize = 0;
@@ -111,19 +114,29 @@
   // Methods providing additional functionality.
   //
 
-  public long getTimeOffset()
+  public synchronized long getTimeOffset()
   {
-    return timeOffset;
+    return (long)(timeOffset * playbackSpeed);
   }
 
   public synchronized void setTimeOffset(long pos)
   {
     // FIXME: Seeking works only in paused mode.
     paused = true;
-    seekOffset = pos;
+    seekOffset = (long)(pos / playbackSpeed);
     notify();
   }
 
+  public synchronized void setSpeed(double newSpeed)
+  {
+    timeOffset = (long)(timeOffset * playbackSpeed / newSpeed);
+    startTime = System.currentTimeMillis() - timeOffset;
+    if (isSeeking()) {
+      seekOffset = (long)(seekOffset * playbackSpeed / newSpeed);
+    }
+    playbackSpeed = newSpeed;
+  }
+
   public boolean isSeeking()
   {
     return (seekOffset >= 0);
@@ -146,7 +159,7 @@
   // Methods for internal use.
   //
 
-  private boolean fillBuffer() throws IOException
+  private synchronized boolean fillBuffer() throws IOException
   {
     waitWhilePaused();
 
@@ -156,8 +169,7 @@
       buffer = new byte[realSize];
       readFully(buffer);
       bufferPos = 0;
-
-      timeOffset = readUnsigned32();
+      timeOffset = (long)(readUnsigned32() / playbackSpeed);
     }
 
     if (bufferSize < 0 || timeOffset < 0) {
@@ -179,11 +191,9 @@
       if (timeDiff <= 0) {
 	break;
       }
-      synchronized(this) {
-	try {
-	  wait(timeDiff);
-	} catch (InterruptedException e) {
-	}
+      try {
+	wait(timeDiff);
+      } catch (InterruptedException e) {
       }
       waitWhilePaused();
     }
diff --git a/java/src/com/tightvnc/rfbplayer/RfbPlayer.java b/java/src/com/tightvnc/rfbplayer/RfbPlayer.java
index 0d87006..55ac568 100644
--- a/java/src/com/tightvnc/rfbplayer/RfbPlayer.java
+++ b/java/src/com/tightvnc/rfbplayer/RfbPlayer.java
@@ -191,10 +191,15 @@
     }
   }
 
+  public void setSpeed(double speed) {
+    fbsStream.setSpeed(speed);
+  }
+
   public void setPos(int pos) {
     fbsStream.setTimeOffset(pos * 1000);
   }
 
+
   public void updatePos() {
     if (showControls)
       buttonPanel.setPos((int)(fbsStream.getTimeOffset() / 1000));