Updating GtkVideoPlayer sample
Handle bus messages, set the XWindowID from a sync handler, use playbin2, ...
This commit is contained in:
parent
aff62828ea
commit
a8161aaf9d
@ -10,7 +10,8 @@ using Gst.BasePlugins;
|
|||||||
|
|
||||||
public class MainWindow : Gtk.Window {
|
public class MainWindow : Gtk.Window {
|
||||||
DrawingArea _da;
|
DrawingArea _da;
|
||||||
Pipeline _pipeline;
|
ulong _xWindowId;
|
||||||
|
PlayBin2 _playbin;
|
||||||
HScale _scale;
|
HScale _scale;
|
||||||
Label _lbl;
|
Label _lbl;
|
||||||
bool _updatingScale;
|
bool _updatingScale;
|
||||||
@ -21,6 +22,19 @@ public class MainWindow : Gtk.Window {
|
|||||||
Gst.Application.Init ();
|
Gst.Application.Init ();
|
||||||
MainWindow window = new MainWindow ();
|
MainWindow window = new MainWindow ();
|
||||||
window.ShowAll ();
|
window.ShowAll ();
|
||||||
|
|
||||||
|
switch (System.Environment.OSVersion.Platform) {
|
||||||
|
case PlatformID.Unix:
|
||||||
|
window._xWindowId = gdk_x11_drawable_get_xid (window._da.GdkWindow.Handle);
|
||||||
|
break;
|
||||||
|
case PlatformID.Win32NT:
|
||||||
|
case PlatformID.Win32S:
|
||||||
|
case PlatformID.Win32Windows:
|
||||||
|
case PlatformID.WinCE:
|
||||||
|
window._xWindowId = (ulong) gdk_win32_drawable_get_handle (window._da.GdkWindow.Handle);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
Gtk.Application.Run ();
|
Gtk.Application.Run ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,6 +45,7 @@ public class MainWindow : Gtk.Window {
|
|||||||
_da = new DrawingArea ();
|
_da = new DrawingArea ();
|
||||||
_da.ModifyBg (Gtk.StateType.Normal, new Gdk.Color (0, 0, 0));
|
_da.ModifyBg (Gtk.StateType.Normal, new Gdk.Color (0, 0, 0));
|
||||||
_da.SetSizeRequest (400, 300);
|
_da.SetSizeRequest (400, 300);
|
||||||
|
_da.DoubleBuffered = false;
|
||||||
vBox.PackStart (_da);
|
vBox.PackStart (_da);
|
||||||
|
|
||||||
_scale = new HScale (0, 1, 0.01);
|
_scale = new HScale (0, 1, 0.01);
|
||||||
@ -75,6 +90,13 @@ public class MainWindow : Gtk.Window {
|
|||||||
|
|
||||||
void OnDeleteEvent (object sender, DeleteEventArgs args) {
|
void OnDeleteEvent (object sender, DeleteEventArgs args) {
|
||||||
Gtk.Application.Quit ();
|
Gtk.Application.Quit ();
|
||||||
|
|
||||||
|
if (_playbin != null) {
|
||||||
|
_playbin.SetState (Gst.State.Null);
|
||||||
|
_playbin.Dispose ();
|
||||||
|
_playbin = null;
|
||||||
|
}
|
||||||
|
|
||||||
args.RetVal = true;
|
args.RetVal = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,47 +107,56 @@ public class MainWindow : Gtk.Window {
|
|||||||
if (dialog.Run () == (int) ResponseType.Accept) {
|
if (dialog.Run () == (int) ResponseType.Accept) {
|
||||||
_pipelineOK = false;
|
_pipelineOK = false;
|
||||||
|
|
||||||
if (_pipeline != null) {
|
if (_playbin != null) {
|
||||||
_pipeline.SetState (Gst.State.Null);
|
_playbin.SetState (Gst.State.Null);
|
||||||
_pipeline.Dispose ();
|
} else {
|
||||||
|
_playbin = new PlayBin2 ();
|
||||||
}
|
}
|
||||||
|
|
||||||
_scale.Value = 0;
|
_scale.Value = 0;
|
||||||
|
|
||||||
_pipeline = new Pipeline (string.Empty);
|
if (_playbin == null)
|
||||||
|
|
||||||
Element playbin = ElementFactory.Make ("playbin", "playbin");
|
|
||||||
XvImageSink sink = XvImageSink.Make ("sink");
|
|
||||||
|
|
||||||
if (_pipeline == null)
|
|
||||||
Console.WriteLine ("Unable to create pipeline");
|
|
||||||
if (playbin == null)
|
|
||||||
Console.WriteLine ("Unable to create element 'playbin'");
|
Console.WriteLine ("Unable to create element 'playbin'");
|
||||||
if (sink == null)
|
|
||||||
Console.WriteLine ("Unable to create element 'sink'");
|
|
||||||
|
|
||||||
_pipeline.Add (playbin);
|
_playbin.Bus.EnableSyncMessageEmission ();
|
||||||
|
_playbin.Bus.AddSignalWatch ();
|
||||||
|
|
||||||
switch (System.Environment.OSVersion.Platform) {
|
_playbin.Bus.SyncMessage += delegate (object bus, SyncMessageArgs sargs) {
|
||||||
case PlatformID.Unix:
|
Gst.Message msg = sargs.Message;
|
||||||
(sink as XOverlay).XwindowId = gdk_x11_drawable_get_xid (_da.GdkWindow.Handle);
|
if (msg == null || msg.Type != Gst.MessageType.Element ||
|
||||||
break;
|
msg.Structure == null || msg.Structure.Name == null ||
|
||||||
case PlatformID.Win32NT:
|
!msg.Structure.Name.Equals ("prepare-xwindow-id"))
|
||||||
case PlatformID.Win32S:
|
return;
|
||||||
case PlatformID.Win32Windows:
|
|
||||||
case PlatformID.WinCE:
|
|
||||||
(sink as XOverlay).XwindowId = (ulong) gdk_win32_drawable_get_handle (_da.GdkWindow.Handle);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
playbin["video-sink"] = sink;
|
(msg.Src as XOverlay).XwindowId = _xWindowId;
|
||||||
playbin["uri"] = "file://" + dialog.Filename;
|
(msg.Src as XOverlay).HandleEvents (true);
|
||||||
|
};
|
||||||
|
|
||||||
StateChangeReturn sret = _pipeline.SetState (Gst.State.Playing);
|
_playbin.Bus.Message += delegate (object bus, MessageArgs margs) {
|
||||||
|
Message message = margs.Message;
|
||||||
|
|
||||||
|
switch (message.Type) {
|
||||||
|
case Gst.MessageType.Error:
|
||||||
|
Enum err;
|
||||||
|
string msg;
|
||||||
|
|
||||||
|
message.ParseError (out err, out msg);
|
||||||
|
Console.WriteLine (String.Format ("Error message: {0}", msg));
|
||||||
|
_pipelineOK = false;
|
||||||
|
break;
|
||||||
|
case Gst.MessageType.Eos:
|
||||||
|
Console.WriteLine ("EOS");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_playbin["uri"] = "file://" + dialog.Filename;
|
||||||
|
|
||||||
|
StateChangeReturn sret = _playbin.SetState (Gst.State.Playing);
|
||||||
|
|
||||||
if (sret == StateChangeReturn.Async) {
|
if (sret == StateChangeReturn.Async) {
|
||||||
State state, pending;
|
State state, pending;
|
||||||
sret = _pipeline.GetState (out state, out pending, Clock.Second * 5);
|
sret = _playbin.GetState (out state, out pending, Clock.Second * 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sret == StateChangeReturn.Success)
|
if (sret == StateChangeReturn.Success)
|
||||||
@ -138,13 +169,13 @@ public class MainWindow : Gtk.Window {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ButtonPlayClicked (object sender, EventArgs args) {
|
void ButtonPlayClicked (object sender, EventArgs args) {
|
||||||
if ( (_pipeline != null) && _pipelineOK)
|
if ( (_playbin != null) && _pipelineOK)
|
||||||
_pipeline.SetState (Gst.State.Playing);
|
_playbin.SetState (Gst.State.Playing);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ButtonPauseClicked (object sender, EventArgs args) {
|
void ButtonPauseClicked (object sender, EventArgs args) {
|
||||||
if ( (_pipeline != null) && _pipelineOK)
|
if ( (_playbin != null) && _pipelineOK)
|
||||||
_pipeline.SetState (Gst.State.Paused);
|
_playbin.SetState (Gst.State.Paused);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScaleValueChanged (object sender, EventArgs args) {
|
void ScaleValueChanged (object sender, EventArgs args) {
|
||||||
@ -154,20 +185,20 @@ public class MainWindow : Gtk.Window {
|
|||||||
long duration;
|
long duration;
|
||||||
Gst.Format fmt = Gst.Format.Time;
|
Gst.Format fmt = Gst.Format.Time;
|
||||||
|
|
||||||
if ( (_pipeline != null) && _pipelineOK && _pipeline.QueryDuration (ref fmt, out duration)) {
|
if ( (_playbin != null) && _pipelineOK && _playbin.QueryDuration (ref fmt, out duration) && duration != -1) {
|
||||||
long pos = (long) (duration * _scale.Value);
|
long pos = (long) (duration * _scale.Value);
|
||||||
//Console.WriteLine ("Seek to {0}/{1} ({2}%)", pos, duration, _scale.Value);
|
Console.WriteLine ("Seek to {0}/{1} ({2}%)", pos, duration, _scale.Value);
|
||||||
|
|
||||||
_pipeline.Seek (Format.Time, SeekFlags.Flush, pos);
|
_playbin.Seek (Format.Time, SeekFlags.Flush | SeekFlags.KeyUnit, pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UpdatePos () {
|
bool UpdatePos () {
|
||||||
Gst.Format fmt = Gst.Format.Time;
|
Gst.Format fmt = Gst.Format.Time;
|
||||||
long duration, pos;
|
long duration, pos;
|
||||||
if ( (_pipeline != null) && _pipelineOK &&
|
if ( (_playbin != null) && _pipelineOK &&
|
||||||
_pipeline.QueryDuration (ref fmt, out duration) &&
|
_playbin.QueryDuration (ref fmt, out duration) &&
|
||||||
_pipeline.QueryPosition (ref fmt, out pos)) {
|
_playbin.QueryPosition (ref fmt, out pos)) {
|
||||||
_lbl.Text = string.Format ("{0} / {1}", TimeString (pos), TimeString (duration));
|
_lbl.Text = string.Format ("{0} / {1}", TimeString (pos), TimeString (duration));
|
||||||
|
|
||||||
_updatingScale = true;
|
_updatingScale = true;
|
||||||
|
@ -17,34 +17,34 @@ assemblies=$(top_builddir)/gstreamer-sharp/gstreamer-sharp.dll
|
|||||||
references=$(addprefix -r:, $(assemblies)) $(GLIB_SHARP_LIBS)
|
references=$(addprefix -r:, $(assemblies)) $(GLIB_SHARP_LIBS)
|
||||||
|
|
||||||
playbin-player.exe: $(srcdir)/PlayBinPlayer.cs $(assemblies)
|
playbin-player.exe: $(srcdir)/PlayBinPlayer.cs $(assemblies)
|
||||||
$(CSC) -out:$@ $(GLIBSHARP_LIBS) $(references) $(srcdir)/PlayBinPlayer.cs
|
$(CSC) -debug -out:$@ $(GLIBSHARP_LIBS) $(references) $(srcdir)/PlayBinPlayer.cs
|
||||||
|
|
||||||
decodebin-transcoder.exe: $(srcdir)/DecodeBinTranscoder.cs $(assemblies)
|
decodebin-transcoder.exe: $(srcdir)/DecodeBinTranscoder.cs $(assemblies)
|
||||||
$(CSC) -out:$@ $(GLIBSHARP_LIBS) $(references) $(srcdir)/DecodeBinTranscoder.cs
|
$(CSC) -debug -out:$@ $(GLIBSHARP_LIBS) $(references) $(srcdir)/DecodeBinTranscoder.cs
|
||||||
|
|
||||||
helloworld.exe: $(srcdir)/HelloWorld.cs $(assemblies)
|
helloworld.exe: $(srcdir)/HelloWorld.cs $(assemblies)
|
||||||
$(CSC) -out:$@ $(GLIBSHARP_LIBS) $(references) $(srcdir)/HelloWorld.cs
|
$(CSC) -debug -out:$@ $(GLIBSHARP_LIBS) $(references) $(srcdir)/HelloWorld.cs
|
||||||
|
|
||||||
typefind.exe: $(srcdir)/TypeFind.cs $(assemblies)
|
typefind.exe: $(srcdir)/TypeFind.cs $(assemblies)
|
||||||
$(CSC) -out:$@ $(GLIBSHARP_LIBS) $(references) $(srcdir)/TypeFind.cs
|
$(CSC) -debug -out:$@ $(GLIBSHARP_LIBS) $(references) $(srcdir)/TypeFind.cs
|
||||||
|
|
||||||
queueexample.exe: $(srcdir)/QueueExample.cs $(assemblies)
|
queueexample.exe: $(srcdir)/QueueExample.cs $(assemblies)
|
||||||
$(CSC) -out:$@ $(GLIBSHARP_LIBS) $(references) $(srcdir)/QueueExample.cs
|
$(CSC) -debug -out:$@ $(GLIBSHARP_LIBS) $(references) $(srcdir)/QueueExample.cs
|
||||||
|
|
||||||
metadata.exe: $(srcdir)/MetaData.cs $(assemblies)
|
metadata.exe: $(srcdir)/MetaData.cs $(assemblies)
|
||||||
$(CSC) -out:$@ $(GLIBSHARP_LIBS) $(references) $(srcdir)/MetaData.cs
|
$(CSC) -debug -out:$@ $(GLIBSHARP_LIBS) $(references) $(srcdir)/MetaData.cs
|
||||||
|
|
||||||
mp3launchparse.exe: $(srcdir)/MP3LaunchParse.cs $(assemblies)
|
mp3launchparse.exe: $(srcdir)/MP3LaunchParse.cs $(assemblies)
|
||||||
$(CSC) -out:$@ $(GLIBSHARP_LIBS) $(references) $(srcdir)/MP3LaunchParse.cs
|
$(CSC) -debug -out:$@ $(GLIBSHARP_LIBS) $(references) $(srcdir)/MP3LaunchParse.cs
|
||||||
|
|
||||||
appsrc.exe: $(srcdir)/AppSrc.cs $(assemblies)
|
appsrc.exe: $(srcdir)/AppSrc.cs $(assemblies)
|
||||||
$(CSC) -out:$@ $(GLIBSHARP_LIBS) $(references) $(MONO_CAIRO_LIBS) $(srcdir)/AppSrc.cs
|
$(CSC) -debug -out:$@ $(GLIBSHARP_LIBS) $(references) $(MONO_CAIRO_LIBS) $(srcdir)/AppSrc.cs
|
||||||
|
|
||||||
transform-sample.exe: $(srcdir)/TransformSample.cs $(assemblies)
|
transform-sample.exe: $(srcdir)/TransformSample.cs $(assemblies)
|
||||||
$(CSC) -out:$@ $(GLIBSHARP_LIBS) $(references) $(MONO_CAIRO_LIBS) $(srcdir)/TransformSample.cs
|
$(CSC) -debug -out:$@ $(GLIBSHARP_LIBS) $(references) $(MONO_CAIRO_LIBS) $(srcdir)/TransformSample.cs
|
||||||
|
|
||||||
gtk-video-player.exe: $(srcdir)/GtkVideoPlayer.cs $(assemblies)
|
gtk-video-player.exe: $(srcdir)/GtkVideoPlayer.cs $(assemblies)
|
||||||
$(CSC) -out:$@ $(GLIBSHARP_LIBS) $(references) $(GTK_SHARP_LIBS) $(srcdir)/GtkVideoPlayer.cs
|
$(CSC) -debug -out:$@ $(GLIBSHARP_LIBS) $(references) $(GTK_SHARP_LIBS) $(srcdir)/GtkVideoPlayer.cs
|
||||||
|
|
||||||
link:
|
link:
|
||||||
ln -sf $(top_builddir)/gstreamer-sharp/gstreamer-sharp.dll gstreamer-sharp.dll
|
ln -sf $(top_builddir)/gstreamer-sharp/gstreamer-sharp.dll gstreamer-sharp.dll
|
||||||
|
Loading…
x
Reference in New Issue
Block a user