Updating GtkVideoPlayer sample

Handle bus messages, set the XWindowID from a sync handler, use playbin2, ...
This commit is contained in:
Sebastian Dröge 2009-10-02 11:53:09 +02:00
parent aff62828ea
commit a8161aaf9d
2 changed files with 81 additions and 50 deletions

View File

@ -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;

View File

@ -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