[longomatch] Update controller API and fix implementation
- From: Andoni Morales Alastruey <amorales src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [longomatch] Update controller API and fix implementation
- Date: Tue, 31 Mar 2015 17:30:27 +0000 (UTC)
commit 5fb4e1c645ec606c4ca2b30ce6ed2f5fcd71f01b
Author: Andoni Morales Alastruey <ylatuya gmail com>
Date: Mon Mar 23 10:55:23 2015 +0100
Update controller API and fix implementation
LongoMatch.Core/Interfaces/IPlayerController.cs | 16 +-
LongoMatch.Services/LongoMatch.Services.csproj | 1 +
LongoMatch.Services/Services/PlayerController.cs | 311 ++++++++++++++--------
3 files changed, 208 insertions(+), 120 deletions(-)
---
diff --git a/LongoMatch.Core/Interfaces/IPlayerController.cs b/LongoMatch.Core/Interfaces/IPlayerController.cs
index bd896bb..1295974 100644
--- a/LongoMatch.Core/Interfaces/IPlayerController.cs
+++ b/LongoMatch.Core/Interfaces/IPlayerController.cs
@@ -31,13 +31,14 @@ namespace LongoMatch.Core.Interfaces
{
event TimeChangedHandler TimeChangedEvent;
event StateChangeHandler PlaybackStateChangedEvent;
- event LoadImageHander LoadImageEvent;
+ event LoadDrawingsHandler LoadDrawingsEvent;
event PlaybackRateChangedHandler PlaybackRateChangedEvent;
event VolumeChangedHandler VolumeChangedEvent;
event ElementLoadedHandler ElementLoadedEvent;
- event ElementUnloadedHandler ElementUnloadedEvent;
event PARChangedHandler PARChangedEvent;
+ MediaFileSet FileSet { get; }
+
Image CurrentMiniatureFrame { get; }
Image CurrentFrame { get; }
@@ -46,6 +47,8 @@ namespace LongoMatch.Core.Interfaces
bool IgnoreTicks { get; set; }
+ bool Opened { get; }
+
object CamerasLayout { get; set; }
List<int> CamerasVisible { get; set; }
@@ -68,5 +71,14 @@ namespace LongoMatch.Core.Interfaces
void UnloadCurrentEvent ();
+ void SeekRelative (double pos);
+
+ bool Seek (Time time, bool accurate = false, bool synchronous = false, bool throttled =
false);
+
+ void Next ();
+
+ void Previous ();
+
+ void Ready ();
}
}
\ No newline at end of file
diff --git a/LongoMatch.Services/LongoMatch.Services.csproj b/LongoMatch.Services/LongoMatch.Services.csproj
index 360351a..e0868d2 100644
--- a/LongoMatch.Services/LongoMatch.Services.csproj
+++ b/LongoMatch.Services/LongoMatch.Services.csproj
@@ -40,6 +40,7 @@
<Compile Include="Services\ToolsManager.cs" />
<Compile Include="Services\FileDB.cs" />
<Compile Include="Services\FileStorage.cs" />
+ <Compile Include="Services\PlayerController.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="..\" />
diff --git a/LongoMatch.Services/Services/PlayerController.cs
b/LongoMatch.Services/Services/PlayerController.cs
index 7b82fb4..8e74ff9 100644
--- a/LongoMatch.Services/Services/PlayerController.cs
+++ b/LongoMatch.Services/Services/PlayerController.cs
@@ -25,21 +25,18 @@ using LongoMatch.Core.Interfaces;
using LongoMatch.Core.Interfaces.Multimedia;
using LongoMatch.Core.Store;
using LongoMatch.Core.Store.Playlists;
-using LongoMatch.Video.Common;
-using LongoMatch.Video.Utils;
using Timer = System.Threading.Timer;
-namespace LongoMatch.Services.Services
+namespace LongoMatch.Services
{
public class PlayerController: IPlayerController
{
public event TimeChangedHandler TimeChangedEvent;
public event StateChangeHandler PlaybackStateChangedEvent;
- public event LoadImageHander LoadImageEvent;
+ public event LoadDrawingsHandler LoadDrawingsEvent;
public event PlaybackRateChangedHandler PlaybackRateChangedEvent;
public event VolumeChangedHandler VolumeChangedEvent;
public event ElementLoadedHandler ElementLoadedEvent;
- public event ElementUnloadedHandler ElementUnloadedEvent;
public event PARChangedHandler PARChangedEvent;
const int TIMEOUT_MS = 20;
@@ -50,12 +47,13 @@ namespace LongoMatch.Services.Services
Playlist loadedPlaylist;
Time streamLenght, videoTS, imageLoadedTS;
- bool readyToSeek, stillimageLoaded;
+ bool readyToSeek, stillimageLoaded, ready, delayedOpen;
MediaFile activeFile;
Seeker seeker;
Segment loadedSegment;
object[] pendingSeek;
Timer timer;
+ IntPtr windowHandle;
struct Segment
{
@@ -76,6 +74,7 @@ namespace LongoMatch.Services.Services
streamLenght = new Time (0);
Step = new Time (5000);
timer = new Timer (HandleTimeout);
+ ready = false;
CreatePlayer ();
}
@@ -106,7 +105,11 @@ namespace LongoMatch.Services.Services
public IntPtr WindowHandle {
set {
- throw new NotImplementedException ();
+ windowHandle = value;
+ player.WindowHandle = value;
+ }
+ get {
+ return windowHandle;
}
}
@@ -154,14 +157,14 @@ namespace LongoMatch.Services.Services
set;
}
- public MediaFileSet MediaFileSet {
+ public MediaFileSet FileSet {
get;
protected set;
}
public bool Opened {
get {
- return MediaFileSet != null;
+ return FileSet != null;
}
}
@@ -181,31 +184,51 @@ namespace LongoMatch.Services.Services
#endregion
-
#region Public methods
- public void Stop ()
+ public void Dispose ()
{
- Pause ();
+ IgnoreTicks = true;
+ timer.Dispose ();
+ player.Dispose ();
}
-
- public void Dispose ()
+ public void Ready ()
{
- throw new NotImplementedException ();
+ Log.Debug ("Player ready");
+ if (delayedOpen) {
+ Log.Debug ("Openning delayed file set");
+ Open (FileSet, true, true);
+ }
+ ready = true;
+ delayedOpen = false;
}
public void Open (MediaFileSet fileSet)
{
- player.Open (fileSet [0].FilePath);
+ Log.Debug ("Openning file set");
+ if (ready) {
+ Open (fileSet, true);
+ } else {
+ Log.Debug ("Player is not ready, delaying ...");
+ delayedOpen = true;
+ }
+ FileSet = fileSet;
+ }
+
+ public void Stop ()
+ {
+ Log.Debug ("Stop");
+ Pause ();
}
public void Play ()
{
+ Log.Debug ("Play");
if (StillImageLoaded) {
ReconfigureTimeout (TIMEOUT_MS);
} else {
- EmitLoadImage (null);
+ EmitLoadDrawings (null);
player.Play ();
}
Playing = true;
@@ -213,6 +236,7 @@ namespace LongoMatch.Services.Services
public void Pause ()
{
+ Log.Debug ("Pause");
if (StillImageLoaded) {
ReconfigureTimeout (0);
} else {
@@ -223,30 +247,39 @@ namespace LongoMatch.Services.Services
public void Close ()
{
+ Log.Debug ("Close");
player.Error -= OnError;
player.StateChange -= OnStateChanged;
player.Eos -= OnEndOfStream;
player.ReadyToSeek -= OnReadyToSeek;
ReconfigureTimeout (0);
player.Dispose ();
- MediaFileSet = null;
+ FileSet = null;
}
public void TogglePlay ()
{
+ Log.Debug ("Toggle playback");
if (Playing)
Pause ();
else
Play ();
}
- public bool Seek (Time time, bool accurate, bool synchronous = false)
+ public bool Seek (Time time, bool accurate, bool synchronous = false, bool throtlled = false)
{
if (!StillImageLoaded) {
- EmitLoadImage (null);
+ EmitLoadDrawings (null);
if (readyToSeek) {
- player.Seek (time + activeFile.Offset, accurate, synchronous);
- OnTick ();
+ if (throtlled) {
+ Log.Debug ("Throttled seek");
+ seeker.Seek (accurate ? SeekType.Accurate :
SeekType.Keyframe, time);
+ } else {
+ Log.Debug (string.Format ("Seeking to {0} accurate:{1}
synchronous:{2} throttled:{3}",
+ time, accurate, synchronous, throtlled));
+ player.Seek (time, accurate, synchronous);
+ OnTick ();
+ }
} else {
Log.Debug ("Delaying seek until player is ready");
pendingSeek = new object[3] { time, 1.0f, false };
@@ -255,10 +288,39 @@ namespace LongoMatch.Services.Services
return true;
}
+ public bool Seek (Time time, bool accurate, bool synchronous)
+ {
+ return Seek (time, accurate, synchronous, false);
+ }
+
+ public void SeekRelative (double pos)
+ {
+ Time seekPos, timePos, duration;
+ bool accurate;
+ bool throthled;
+
+ Log.Debug (string.Format ("Seek relative to {0}", pos));
+ if (SegmentLoaded) {
+ duration = loadedSegment.Stop - loadedSegment.Start;
+ timePos = duration * pos;
+ seekPos = loadedSegment.Start + timePos;
+ accurate = true;
+ throthled = true;
+ } else {
+ duration = streamLenght;
+ seekPos = timePos = streamLenght * pos;
+ accurate = false;
+ throthled = false;
+ }
+ Seek (seekPos, accurate, false, throthled);
+ EmitTimeChanged (timePos, duration);
+ }
+
public bool SeekToNextFrame ()
{
+ Log.Debug ("Seek to next frame");
if (!StillImageLoaded) {
- EmitLoadImage (null);
+ EmitLoadDrawings (null);
if (CurrentTime < loadedSegment.Stop) {
player.SeekToNextFrame ();
OnTick ();
@@ -269,8 +331,9 @@ namespace LongoMatch.Services.Services
public bool SeekToPreviousFrame ()
{
+ Log.Debug ("Seek to previous frame");
if (!StillImageLoaded) {
- EmitLoadImage (null);
+ EmitLoadDrawings (null);
if (CurrentTime > loadedSegment.Start) {
seeker.Seek (SeekType.StepDown);
}
@@ -280,26 +343,29 @@ namespace LongoMatch.Services.Services
public void StepForward ()
{
+ Log.Debug ("Step forward");
if (StillImageLoaded) {
return;
}
- EmitLoadImage (null);
+ EmitLoadDrawings (null);
DoStep (Step);
}
public void StepBackward ()
{
+ Log.Debug ("Step backward");
if (StillImageLoaded) {
return;
}
- EmitLoadImage (null);
+ EmitLoadDrawings (null);
DoStep (new Time (-Step.MSeconds));
}
public void FramerateUp ()
{
+ Log.Debug ("Framerate up");
if (!StillImageLoaded) {
- EmitLoadImage (null);
+ EmitLoadDrawings (null);
}
/* FIXME */
@@ -308,8 +374,9 @@ namespace LongoMatch.Services.Services
public void FramerateDown ()
{
+ Log.Debug ("Framerate down");
if (!StillImageLoaded) {
- EmitLoadImage (null);
+ EmitLoadDrawings (null);
}
/* FIXME */
//vscale1.Adjustment.Value -= vscale1.Adjustment.StepIncrement;
@@ -322,10 +389,11 @@ namespace LongoMatch.Services.Services
public void LoadPlayListEvent (Playlist playlist, IPlaylistElement element)
{
+ Log.Debug (string.Format ("Loading playlist element \"{0}\"", element.Description));
+
loadedEvent = null;
loadedPlaylist = playlist;
loadedPlaylistElement = element;
- EmitElementLoaded (playlist.HasNext ());
if (element is PlaylistPlayElement) {
PlaylistPlayElement ple = element as PlaylistPlayElement;
@@ -338,10 +406,13 @@ namespace LongoMatch.Services.Services
} else if (element is PlaylistDrawing) {
LoadFrameDrawing (element as PlaylistDrawing);
}
+ EmitElementLoaded (element, playlist.HasNext ());
}
public void LoadEvent (MediaFileSet fileSet, TimelineEvent evt, Time seekTime, bool playing)
{
+ Log.Debug (string.Format ("Loading event \"{0}\" seek:{1} playing:{2}", evt.Name,
seekTime, playing));
+
loadedPlaylist = null;
loadedPlaylistElement = null;
loadedEvent = evt;
@@ -352,41 +423,59 @@ namespace LongoMatch.Services.Services
} else {
Log.Error ("Event does not have timing info: " + evt);
}
+ EmitElementLoaded (evt, false);
}
public void UnloadCurrentEvent ()
{
+ Log.Debug ("Unload current event");
+ Reset ();
EmitEventUnloaded ();
- SetRate (1);
- StillImageLoaded = false;
- loadedSegment.Start = new Time (-1);
- loadedSegment.Stop = new Time (int.MaxValue);
- loadedEvent = null;
+ }
+
+ public void Next ()
+ {
+ Log.Debug ("Next");
+ if (loadedPlaylistElement != null && loadedPlaylist.HasNext ()) {
+ Config.EventsBroker.EmitNextPlaylistElement (loadedPlaylist);
+ }
+ }
+
+ public void Previous ()
+ {
+ Log.Debug ("Previous");
+ if (loadedPlaylistElement != null) {
+ if (loadedPlaylist.HasPrev ()) {
+ Config.EventsBroker.EmitPreviousPlaylistElement (loadedPlaylist);
+ }
+ } else if (loadedEvent != null) {
+ Seek (loadedEvent.Start, true);
+ } else {
+ Seek (new Time (0), true);
+ }
}
#endregion
#region Signals
- void EmitLoadImage (Image image, FrameDrawing drawing = null, bool isStill = false)
+ void EmitLoadDrawings (FrameDrawing drawing = null)
{
- if (LoadImageEvent != null) {
- LoadImageEvent (image, drawing);
+ if (LoadDrawingsEvent != null) {
+ LoadDrawingsEvent (drawing);
}
}
- void EmitElementLoaded (bool hasNext)
+ void EmitElementLoaded (object element, bool hasNext)
{
if (ElementLoadedEvent != null) {
- ElementLoadedEvent (hasNext);
+ ElementLoadedEvent (element, hasNext);
}
}
void EmitEventUnloaded ()
{
- if (ElementUnloadedEvent != null) {
- ElementUnloadedEvent ();
- }
+ EmitElementLoaded (null, false);
}
void EmitRateChanged (float rate)
@@ -406,14 +495,14 @@ namespace LongoMatch.Services.Services
void EmitTimeChanged (Time currentTime, Time duration)
{
if (TimeChangedEvent != null) {
- TimeChangedEvent (currentTime, duration, StillImageLoaded);
+ TimeChangedEvent (currentTime, duration, !StillImageLoaded);
}
}
- void EmitPARChanged (float par)
+ void EmitPARChanged (IntPtr windowHandle, float par)
{
if (PARChangedEvent != null) {
- PARChangedEvent (par);
+ PARChangedEvent (windowHandle, par);
}
}
@@ -428,37 +517,17 @@ namespace LongoMatch.Services.Services
#region Private methods
- void SetRate (float rate)
- {
- Rate = rate;
- EmitRateChanged (rate);
- }
-
- bool StillImageLoaded {
- set {
- stillimageLoaded = value;
- if (stillimageLoaded) {
- player.Pause ();
- imageLoadedTS = new Time (0);
- ReconfigureTimeout (TIMEOUT_MS);
- }
- }
- get {
- return stillimageLoaded;
- }
- }
-
void Open (MediaFileSet fileSet, bool seek, bool force = false, bool play = false)
{
- UnloadCurrentEvent ();
- if (fileSet != this.MediaFileSet || force) {
+ Reset ();
+ if (fileSet != this.FileSet || force) {
readyToSeek = false;
- MediaFileSet = fileSet;
+ FileSet = fileSet;
activeFile = fileSet.First ();
if (activeFile.VideoHeight != 0) {
- EmitPARChanged ((float)(activeFile.VideoWidth * activeFile.Par /
activeFile.VideoHeight));
+ EmitPARChanged (WindowHandle, (float)(activeFile.VideoWidth *
activeFile.Par / activeFile.VideoHeight));
} else {
- EmitPARChanged (1);
+ EmitPARChanged (WindowHandle, 1);
}
try {
Log.Debug ("Opening new file " + activeFile.FilePath);
@@ -477,6 +546,35 @@ namespace LongoMatch.Services.Services
}
}
+ void Reset ()
+ {
+ SetRate (1);
+ StillImageLoaded = false;
+ loadedSegment.Start = new Time (-1);
+ loadedSegment.Stop = new Time (int.MaxValue);
+ loadedEvent = null;
+ }
+
+ void SetRate (float rate)
+ {
+ Rate = rate;
+ EmitRateChanged (rate);
+ }
+
+ bool StillImageLoaded {
+ set {
+ stillimageLoaded = value;
+ if (stillimageLoaded) {
+ player.Pause ();
+ imageLoadedTS = new Time (0);
+ ReconfigureTimeout (TIMEOUT_MS);
+ }
+ }
+ get {
+ return stillimageLoaded;
+ }
+ }
+
bool SegmentLoaded {
get {
return loadedSegment.Start.MSeconds != -1;
@@ -500,14 +598,13 @@ namespace LongoMatch.Services.Services
Log.Debug (String.Format ("Update player segment {0} {1} {2}",
start.ToMSecondsString (),
stop.ToMSecondsString (), rate));
- if (fileSet != this.MediaFileSet) {
+ if (fileSet != this.FileSet) {
Open (fileSet, false);
}
Pause ();
loadedSegment.Start = start;
loadedSegment.Stop = stop;
rate = rate == 0 ? 1 : rate;
- EmitElementLoaded (false);
StillImageLoaded = false;
if (readyToSeek) {
Log.Debug ("Player is ready to seek, seeking to " +
@@ -523,25 +620,16 @@ namespace LongoMatch.Services.Services
}
}
- void LoadImage (Image image, FrameDrawing drawing)
- {
- EmitLoadImage (image, drawing);
- }
-
void LoadStillImage (PlaylistImage image)
{
loadedPlaylistElement = image;
- UnloadCurrentEvent ();
StillImageLoaded = true;
- LoadImage (image.Image, null);
}
void LoadFrameDrawing (PlaylistDrawing drawing)
{
loadedPlaylistElement = drawing;
- UnloadCurrentEvent ();
StillImageLoaded = true;
- LoadImage (null, drawing.Drawing);
}
void LoadVideo (PlaylistVideo video)
@@ -556,9 +644,9 @@ namespace LongoMatch.Services.Services
{
Pause ();
IgnoreTicks = true;
- player.Seek (drawing.Render + activeFile.Offset, true, true);
+ player.Seek (drawing.Render, true, true);
IgnoreTicks = false;
- LoadImage (CurrentFrame, drawing);
+ EmitLoadDrawings (drawing);
}
void DoStep (Time step)
@@ -568,28 +656,10 @@ namespace LongoMatch.Services.Services
pos.MSeconds = 0;
Log.Debug (String.Format ("Stepping {0} seconds from {1} to {2}",
step, CurrentTime, pos));
- EmitLoadImage (null);
+ EmitLoadDrawings (null);
Seek (pos, true);
}
- void SeekFromTimescale (double pos)
- {
- Time seekPos, duration;
- SeekType seekType;
-
- if (SegmentLoaded) {
- duration = loadedSegment.Stop - loadedSegment.Start;
- seekPos = loadedSegment.Start + duration * pos;
- seekType = SeekType.Accurate;
- } else {
- duration = streamLenght;
- seekPos = streamLenght * pos;
- seekType = SeekType.Keyframe;
- }
- seeker.Seek (seekType, seekPos);
- EmitTimeChanged (seekPos, duration);
- }
-
void CreatePlayer ()
{
player = Config.MultimediaToolkit.GetPlayer ();
@@ -634,6 +704,7 @@ namespace LongoMatch.Services.Services
pendingSeek = null;
}
OnTick ();
+ player.Expose ();
}
#endregion
@@ -681,7 +752,9 @@ namespace LongoMatch.Services.Services
void HandleTimeout (Object state)
{
- OnTick ();
+ Config.DrawingToolkit.Invoke (delegate {
+ OnTick ();
+ });
}
bool OnTick ()
@@ -730,21 +803,23 @@ namespace LongoMatch.Services.Services
void HandleSeekEvent (SeekType type, Time start, float rate)
{
- EmitLoadImage (null, null);
- /* We only use it for backwards framestepping for now */
- if (type == SeekType.StepDown || type == SeekType.StepUp) {
- if (player.Playing)
- Pause ();
- if (type == SeekType.StepDown)
- player.SeekToPreviousFrame ();
- else
- player.SeekToNextFrame ();
- OnTick ();
- }
- if (type == SeekType.Accurate || type == SeekType.Keyframe) {
- SetRate (rate);
- Seek (start, type == SeekType.Accurate);
- }
+ Config.DrawingToolkit.Invoke (delegate {
+ EmitLoadDrawings (null);
+ /* We only use it for backwards framestepping for now */
+ if (type == SeekType.StepDown || type == SeekType.StepUp) {
+ if (player.Playing)
+ Pause ();
+ if (type == SeekType.StepDown)
+ player.SeekToPreviousFrame ();
+ else
+ player.SeekToNextFrame ();
+ OnTick ();
+ }
+ if (type == SeekType.Accurate || type == SeekType.Keyframe) {
+ SetRate (rate);
+ Seek (start, type == SeekType.Accurate, false, false);
+ }
+ });
}
#endregion
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]