[gnome-subtitles] Fix bug #453469 - Slow and Fast Motion Option, based on a patch from Keith.



commit 6049c758a93db352b4cee76bb85170d77894f296
Author: Pedro Castro <mail pedrocastro org>
Date:   Mon May 9 00:22:47 2011 +0100

    Fix bug #453469 - Slow and Fast Motion Option, based on a patch from Keith.

 src/External/GStreamerPlaybin/Engine.cs      |   16 +++---
 src/External/GStreamerPlaybin/main.c         |    9 ++-
 src/Glade/MainWindow.glade                   |   72 +++++++++++++++++++++++-
 src/GnomeSubtitles/Core/EventHandlers.cs     |   12 ++++
 src/GnomeSubtitles/Ui/VideoPreview/Player.cs |   80 +++++++++++++++++++-------
 src/GnomeSubtitles/Ui/VideoPreview/Video.cs  |   22 +++++++
 src/GnomeSubtitles/Ui/WidgetNames.cs         |    3 +
 7 files changed, 179 insertions(+), 35 deletions(-)
---
diff --git a/src/External/GStreamerPlaybin/Engine.cs b/src/External/GStreamerPlaybin/Engine.cs
index 94d289c..aecb197 100644
--- a/src/External/GStreamerPlaybin/Engine.cs
+++ b/src/External/GStreamerPlaybin/Engine.cs
@@ -1,6 +1,7 @@
 /*
 
 	Copyright (C) 2007 Goran Sterjov, Pedro Castro
+	Copyright (C) 2011 Pedro Castro
 
     This file is part of the GStreamer Playbin Wrapper.
     Derived from Fuse.
@@ -38,7 +39,7 @@ namespace GStreamer
 	public delegate void ErrorEventHandler (ErrorEventArgs args);
 	public delegate void BufferEventHandler (BufferEventArgs args);
 	public delegate void EndOfStreamEventHandler ();
-	
+
 	public delegate void StateEventHandler (StateEventArgs args);
 	public delegate void VideoInfoEventHandler (VideoInfoEventArgs args);
 	public delegate void TagEventHandler (TagEventArgs args);
@@ -212,25 +213,24 @@ namespace GStreamer
 		/// <summary>
 		/// Seeks to the nearest millisecond on the media file.
 		/// </summary>
-		public void Seek (TimeSpan time)
+		public void Seek (TimeSpan time, float speed)
 		{
 			if (isUnloaded)
 				return;
 			
-			gst_binding_set_position (engine, (ulong) time.TotalMilliseconds);
+			gst_binding_set_position (engine, (ulong) time.TotalMilliseconds, speed);
 		}
 		
 		
 		/// <summary>
 		/// Seeks to the nearest millisecond on the media file.
 		/// </summary>
-		public void Seek (double milliseconds)
+		public void Seek (double milliseconds, float speed)
 		{
 			TimeSpan time = TimeSpan.FromMilliseconds (milliseconds);
-			Seek (time);
+			Seek (time, speed);
 		}
 		
-		
 		/// <summary>
 		/// Seeks to the specified track number.
 		/// </summary>
@@ -491,7 +491,7 @@ namespace GStreamer
 		[DllImport("gstreamer_playbin")]
 		static extern int gst_binding_get_volume (HandleRef play);
 		[DllImport("gstreamer_playbin")]
-		static extern void gst_binding_set_position (HandleRef play, ulong pos);
+		static extern void gst_binding_set_position (HandleRef play, ulong pos, float speed);
 		[DllImport("gstreamer_playbin")]
 		static extern void gst_binding_set_track (HandleRef play, ulong track_number);
 		[DllImport("gstreamer_playbin")]
@@ -587,4 +587,4 @@ namespace GStreamer
     }
 	
 	
-}
\ No newline at end of file
+}
diff --git a/src/External/GStreamerPlaybin/main.c b/src/External/GStreamerPlaybin/main.c
index 8d94fea..b71576a 100644
--- a/src/External/GStreamerPlaybin/main.c
+++ b/src/External/GStreamerPlaybin/main.c
@@ -1,6 +1,7 @@
 /*
 
 	Copyright (C) 2007 Goran Sterjov, Pedro Castro
+	Copyright (C) 2011 Pedro Castro
 
     This file is part of the GStreamer Playbin Wrapper.
     Derived from Fuse.
@@ -341,20 +342,20 @@ guint64 gst_binding_get_position (gstPlay *play) {
 }
 
 // set the position of the media file
-void gst_binding_set_position (gstPlay *play, gint64 time_sec) {
+void gst_binding_set_position (gstPlay *play, gint64 time_sec, float speed) {
 	if (!isValid (play)) return;
 	
-	gst_element_seek (play->element, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH,
+	gst_element_seek (play->element, speed, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH,
 					  GST_SEEK_TYPE_SET, time_sec * GST_MSECOND,
 					  GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
 }
 
 
 // set the position of the media file
-void gst_binding_set_track (gstPlay *play, gint64 track_number) {
+void gst_binding_set_track (gstPlay *play, gint64 track_number, float speed) {
 	if (!isValid (play)) return;
 	
-	gst_element_seek (play->element, 1.0, gst_format_get_by_nick ("track"),
+	gst_element_seek (play->element, speed, gst_format_get_by_nick ("track"),
 	      GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, track_number - 1,
 	      GST_SEEK_TYPE_NONE, -1);
 }
diff --git a/src/Glade/MainWindow.glade b/src/Glade/MainWindow.glade
index a9c457c..faf6be9 100644
--- a/src/Glade/MainWindow.glade
+++ b/src/Glade/MainWindow.glade
@@ -1653,6 +1653,76 @@
                           </packing>
                         </child>
                         <child>
+                          <widget class="GtkHBox" id="speedHBox">
+                            <property name="visible">True</property>
+                            <child>
+                              <widget class="GtkButton" id="videoSpeedDownButton">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">True</property>
+                                <property name="relief">none</property>
+                                <signal name="clicked" handler="OnVideoSpeedDown"/>
+                                <accelerator key="minus" signal="activate" modifiers="GDK_CONTROL_MASK"/>
+                                <child>
+                                  <widget class="GtkImage" id="videoSpeedDownButtonImage">
+                                    <property name="visible">True</property>
+                                    <property name="stock">gtk-remove</property>
+                                    <property name="icon-size">1</property>
+                                  </widget>
+                                </child>
+                              </widget>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">False</property>
+                                <property name="position">0</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <widget class="GtkButton" id="videoSpeedButton">
+                                <property name="label">1.0x</property>
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">True</property>
+                                <property name="relief">none</property>
+                                <property name="focus_on_click">False</property>
+                                <signal name="clicked" handler="OnVideoSpeed"/>
+                              </widget>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">False</property>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <widget class="GtkButton" id="videoSpeedUpButton">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">True</property>
+                                <property name="relief">none</property>
+                                <signal name="clicked" handler="OnVideoSpeedUp"/>
+                                <accelerator key="plus" signal="activate" modifiers="GDK_CONTROL_MASK"/>
+                                <child>
+                                  <widget class="GtkImage" id="videoSpeedUpButtonImage">
+                                    <property name="visible">True</property>
+                                    <property name="stock">gtk-add</property>
+                                    <property name="icon-size">1</property>
+                                  </widget>
+                                </child>
+                              </widget>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">False</property>
+                                <property name="position">2</property>
+                              </packing>
+                            </child>
+                          </widget>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                        <child>
                           <widget class="GtkHScale" id="videoSlider">
                             <property name="visible">True</property>
                             <property name="adjustment">0 0 100 0.5 10 10</property>
@@ -1660,7 +1730,7 @@
                             <property name="value_pos">bottom</property>
                           </widget>
                           <packing>
-                            <property name="position">1</property>
+                            <property name="position">2</property>
                           </packing>
                         </child>
                       </widget>
diff --git a/src/GnomeSubtitles/Core/EventHandlers.cs b/src/GnomeSubtitles/Core/EventHandlers.cs
index d9dfb5f..0697bd8 100644
--- a/src/GnomeSubtitles/Core/EventHandlers.cs
+++ b/src/GnomeSubtitles/Core/EventHandlers.cs
@@ -250,6 +250,18 @@ public class EventHandlers {
 		Base.Ui.Video.Forward();
 	}
 	
+	public void OnVideoSpeedUp (object o, EventArgs args) {
+	    Base.Ui.Video.SpeedUp();
+	} 
+	
+	public void OnVideoSpeedDown (object o, EventArgs args) {
+	    Base.Ui.Video.SpeedDown();
+	}
+	
+	public void OnVideoSpeed (object o, EventArgs args) {
+	    Base.Ui.Video.SpeedReset();
+	} 
+	
 	public void OnVideoSeekTo (object o, EventArgs args) {
 		Base.Dialogs.Get(typeof(VideoSeekToDialog)).Show();
 	}
diff --git a/src/GnomeSubtitles/Ui/VideoPreview/Player.cs b/src/GnomeSubtitles/Ui/VideoPreview/Player.cs
index 9a406ef..48a4512 100644
--- a/src/GnomeSubtitles/Ui/VideoPreview/Player.cs
+++ b/src/GnomeSubtitles/Ui/VideoPreview/Player.cs
@@ -30,6 +30,7 @@ public delegate void PlayerErrorEventHandler (Uri videoUri, Exception e);
 public delegate void VideoDurationEventHandler (TimeSpan duration);
 
 public class Player {
+    
 	private AspectFrame frame = null;
 	private Socket socket = null;
 	private Playbin playbin = null;
@@ -37,9 +38,13 @@ public class Player {
 	private bool hasFoundDuration = false;
 	private Uri videoUri = null;
 	private VideoInfo videoInfo = null;
+	private float speed = 1;
 
 	/* Constants */
 	public const float DefaultAspectRatio = 1.67f;
+	public const float DefaultMinSpeed = 0.1f;
+	public const float DefaultSpeedStep = 0.1f;
+	public const float DefaultMaxSpeed = 2;
 
 	public Player (AspectFrame aspectFrame) {
 		this.frame = aspectFrame;
@@ -49,23 +54,6 @@ public class Player {
 		InitializePlaybin();
 	}
 	
-	private void InitializePlaybin () {
-		playbin = new Playbin();
-		
-		if (!playbin.Initiate(socket.Id))
-			throw new PlayerCouldNotInitiateEngineException();
-		
-		playbin.Error += OnPlaybinError;
-		playbin.EndOfStream += OnPlaybinEndOfStream;
-		playbin.StateChanged += OnPlaybinStateChanged;
-		playbin.FoundVideoInfo += OnPlaybinFoundVideoInfo;
-		playbin.FoundTag += OnPlaybinFoundTag;
-	}
-	
-	private void InitializePositionWatcher () {
-		position = new PlayerPositionWatcher(GetPosition);
-		position.Changed += OnPositionWatcherChanged;		
-	}
 	
 	/* Events */
 	public event PlayerErrorEventHandler Error;
@@ -112,6 +100,10 @@ public class Player {
 	public Uri VideoUri {
 		get { return videoUri; }
 	}
+	
+	public float Speed {
+		get { return speed; }
+	}
 
 
 	/* Public methods */
@@ -130,6 +122,7 @@ public class Player {
 		videoUri = null;
 		hasFoundDuration = false;
 		videoInfo = null;
+		speed = 1;
 	}
 
 	public void Play () {
@@ -140,6 +133,27 @@ public class Player {
 		playbin.Pause();
 	}
 	
+    public void SpeedUp () {
+        if (this.speed >= DefaultMaxSpeed)
+	        return;
+
+		this.speed += DefaultSpeedStep;
+		ChangeSpeed(this.speed);
+	}
+	
+	public void SpeedDown () {
+	    if (this.speed <= DefaultMinSpeed)
+	        return;
+
+	    this.speed -= DefaultSpeedStep;
+		ChangeSpeed(this.speed);
+	}
+	
+	public void SpeedReset () {
+		this.speed = 1;
+		ChangeSpeed(this.speed);
+	}
+	
 	public void Rewind (TimeSpan dec) {
 		Seek(playbin.CurrentPosition - dec);
 	}
@@ -147,13 +161,13 @@ public class Player {
 	public void Forward (TimeSpan inc) {
 		Seek(playbin.CurrentPosition + inc);
 	}
-
+	
 	public void Seek (TimeSpan newPosition) {
-		playbin.Seek(newPosition);
+		playbin.Seek(newPosition, speed);
 	}
 	
 	public void Seek (double newPosition) {
-		playbin.Seek(newPosition); // newPosition in milliseconds
+		playbin.Seek(newPosition, speed); // newPosition in milliseconds
 	}
 	
 	public void Dispose () {
@@ -174,12 +188,34 @@ public class Player {
 		socket.Show();
 	}
 	
+	private void InitializePlaybin () {
+		playbin = new Playbin();
+		
+		if (!playbin.Initiate(socket.Id))
+			throw new PlayerCouldNotInitiateEngineException();
+		
+		playbin.Error += OnPlaybinError;
+		playbin.EndOfStream += OnPlaybinEndOfStream;
+		playbin.StateChanged += OnPlaybinStateChanged;
+		playbin.FoundVideoInfo += OnPlaybinFoundVideoInfo;
+		playbin.FoundTag += OnPlaybinFoundTag;
+	}
+	
+	private void InitializePositionWatcher () {
+		position = new PlayerPositionWatcher(GetPosition);
+		position.Changed += OnPositionWatcherChanged;		
+	}
+	
 	/// <summary>Gets the current player position.</summary>
 	private TimeSpan GetPosition () {
 		return playbin.CurrentPosition;
 	}
 
-	
+	private void ChangeSpeed (float newSpeed) {
+	    playbin.Seek(playbin.CurrentPosition, newSpeed);
+	}
+
+		
 	/* Event members */
 	
 	private void OnPlaybinError (ErrorEventArgs args) {
@@ -236,4 +272,4 @@ public class Player {
 	
 }
 
-}
\ No newline at end of file
+}
diff --git a/src/GnomeSubtitles/Ui/VideoPreview/Video.cs b/src/GnomeSubtitles/Ui/VideoPreview/Video.cs
index 3a9d8a1..c1b4440 100644
--- a/src/GnomeSubtitles/Ui/VideoPreview/Video.cs
+++ b/src/GnomeSubtitles/Ui/VideoPreview/Video.cs
@@ -158,6 +158,21 @@ public class Video {
 		player.Forward(position.SeekIncrement);
 	}
 	
+	public void SpeedUp () {
+	    player.SpeedUp();
+	    UpdateSpeedControls(player.Speed);
+	}
+	
+	public void SpeedDown () {
+	    player.SpeedDown();
+	    UpdateSpeedControls(player.Speed);
+	}
+	
+	public void SpeedReset () {
+	    player.SpeedReset();
+	    UpdateSpeedControls(player.Speed);
+	}
+	
 	/// <summary>Seeks to the specified time.</summary>
 	/// <param name="time">The time position to seek to, in seconds.</param>
 	public void Seek (TimeSpan time) {
@@ -202,6 +217,13 @@ public class Video {
 	private void Pause () {
 		player.Pause();
 	}
+	
+	private void UpdateSpeedControls (float speed) {
+		(Base.GetWidget(WidgetNames.VideoSpeedButton) as Button).Label = String.Format("{0:0.0}x", speed);
+		
+		Base.GetWidget(WidgetNames.VideoSpeedDownButton).Sensitive = (speed > Player.DefaultMinSpeed);
+		Base.GetWidget(WidgetNames.VideoSpeedUpButton).Sensitive = (speed < Player.DefaultMaxSpeed);
+	}
 
 	private void SetCustomIcons () {
 		/* Set the icon for the SetSubtitleStart button */
diff --git a/src/GnomeSubtitles/Ui/WidgetNames.cs b/src/GnomeSubtitles/Ui/WidgetNames.cs
index bae661e..069b04d 100644
--- a/src/GnomeSubtitles/Ui/WidgetNames.cs
+++ b/src/GnomeSubtitles/Ui/WidgetNames.cs
@@ -126,6 +126,9 @@ public class WidgetNames {
 	public const string VideoPlaybackHBox = "videoPlaybackHBox";
 	public const string VideoSlider = "videoSlider";
 	public const string VideoPlayPauseButton = "videoPlayPauseButton";
+	public const string VideoSpeedButton = "videoSpeedButton";
+	public const string VideoSpeedUpButton = "videoSpeedUpButton";
+	public const string VideoSpeedDownButton = "videoSpeedDownButton";
 
 
 	/* Subtitle area */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]