mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-20 15:27:07 +00:00
Update samples from http://code.google.com/p/cil-bindings
Also add a XvImageSink binding and add the GtkVideoPlayer sample from the above place.
This commit is contained in:
parent
e028718bb3
commit
c54dc8ce93
4 changed files with 385 additions and 134 deletions
54
gstreamer-sharp/baseplugins/XvImageSink.cs
Normal file
54
gstreamer-sharp/baseplugins/XvImageSink.cs
Normal file
|
@ -0,0 +1,54 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Gst;
|
||||
using Gst.Interfaces;
|
||||
|
||||
namespace Gst.BasePlugins {
|
||||
[GTypeName ("GstXvImageSink") ]
|
||||
public class XvImageSink : Element, XOverlay {
|
||||
public XvImageSink (IntPtr raw) : base (raw) { }
|
||||
|
||||
public static XvImageSink Make (string name) {
|
||||
return ElementFactory.Make ("xvimagesink", name) as XvImageSink;
|
||||
}
|
||||
|
||||
[DllImport ("gstinterfaces-0.10.dll") ]
|
||||
static extern void gst_x_overlay_expose (IntPtr raw);
|
||||
|
||||
public void Expose() {
|
||||
gst_x_overlay_expose (Handle);
|
||||
}
|
||||
|
||||
[DllImport ("gstinterfaces-0.10.dll") ]
|
||||
static extern void gst_x_overlay_handle_events (IntPtr raw, bool handle_events);
|
||||
|
||||
public void HandleEvents (bool handle_events) {
|
||||
gst_x_overlay_handle_events (Handle, handle_events);
|
||||
}
|
||||
|
||||
[DllImport ("gstinterfaces-0.10.dll") ]
|
||||
static extern void gst_x_overlay_got_xwindow_id (IntPtr raw, UIntPtr xwindow_id);
|
||||
|
||||
public void GotXwindowId (ulong xwindow_id) {
|
||||
gst_x_overlay_got_xwindow_id (Handle, new UIntPtr (xwindow_id));
|
||||
}
|
||||
|
||||
[DllImport ("gstinterfaces-0.10.dll") ]
|
||||
static extern void gst_x_overlay_prepare_xwindow_id (IntPtr raw);
|
||||
|
||||
public void PrepareXwindowId() {
|
||||
gst_x_overlay_prepare_xwindow_id (Handle);
|
||||
}
|
||||
|
||||
[DllImport ("gstinterfaces-0.10.dll") ]
|
||||
static extern void gst_x_overlay_set_xwindow_id (IntPtr raw, UIntPtr xwindow_id);
|
||||
|
||||
public ulong XwindowId {
|
||||
set {
|
||||
gst_x_overlay_set_xwindow_id (Handle, new UIntPtr (value));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
188
samples/GtkVideoPlayer.cs
Normal file
188
samples/GtkVideoPlayer.cs
Normal file
|
@ -0,0 +1,188 @@
|
|||
// Authors
|
||||
// Copyright (C) 2008 Paul Burton <paulburton89@gmail.com>
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using Gtk;
|
||||
using Gst;
|
||||
using Gst.Interfaces;
|
||||
using Gst.BasePlugins;
|
||||
|
||||
public class MainWindow : Gtk.Window {
|
||||
DrawingArea _da;
|
||||
Pipeline _pipeline;
|
||||
HScale _scale;
|
||||
Label _lbl;
|
||||
bool _updatingScale;
|
||||
bool _pipelineOK;
|
||||
|
||||
public static void Main (string[] args) {
|
||||
Gtk.Application.Init ();
|
||||
Gst.Application.Init ();
|
||||
MainWindow window = new MainWindow ();
|
||||
window.ShowAll ();
|
||||
Gtk.Application.Run ();
|
||||
}
|
||||
|
||||
public MainWindow ()
|
||||
: base (WindowType.Toplevel) {
|
||||
VBox vBox = new VBox ();
|
||||
|
||||
_da = new DrawingArea ();
|
||||
_da.ModifyBg (Gtk.StateType.Normal, new Gdk.Color (0, 0, 0));
|
||||
_da.SetSizeRequest (400, 300);
|
||||
vBox.PackStart (_da);
|
||||
|
||||
_scale = new HScale (0, 1, 0.01);
|
||||
_scale.DrawValue = false;
|
||||
_scale.ValueChanged += ScaleValueChanged;
|
||||
vBox.PackStart (_scale, false, false, 0);
|
||||
|
||||
HBox hBox = new HBox ();
|
||||
|
||||
Button btnOpen = new Button ();
|
||||
btnOpen.Label = "Open";
|
||||
btnOpen.Clicked += ButtonOpenClicked;
|
||||
|
||||
hBox.PackStart (btnOpen, false, false, 0);
|
||||
|
||||
Button btnPlay = new Button ();
|
||||
btnPlay.Label = "Play";
|
||||
btnPlay.Clicked += ButtonPlayClicked;
|
||||
|
||||
hBox.PackStart (btnPlay, false, false, 0);
|
||||
|
||||
Button btnPause = new Button ();
|
||||
btnPause.Label = "Pause";
|
||||
btnPause.Clicked += ButtonPauseClicked;
|
||||
|
||||
hBox.PackStart (btnPause, false, false, 0);
|
||||
|
||||
_lbl = new Label ();
|
||||
_lbl.Text = "00:00 / 00:00";
|
||||
|
||||
hBox.PackEnd (_lbl, false, false, 0);
|
||||
|
||||
vBox.PackStart (hBox, false, false, 3);
|
||||
|
||||
Add (vBox);
|
||||
|
||||
WindowPosition = Gtk.WindowPosition.Center;
|
||||
DeleteEvent += OnDeleteEvent;
|
||||
|
||||
GLib.Timeout.Add (1000, new GLib.TimeoutHandler (UpdatePos));
|
||||
}
|
||||
|
||||
void OnDeleteEvent (object sender, DeleteEventArgs args) {
|
||||
Gtk.Application.Quit ();
|
||||
args.RetVal = true;
|
||||
}
|
||||
|
||||
void ButtonOpenClicked (object sender, EventArgs args) {
|
||||
FileChooserDialog dialog = new FileChooserDialog ("Open", this, FileChooserAction.Open, new object[] { "Cancel", ResponseType.Cancel, "Open", ResponseType.Accept });
|
||||
dialog.SetCurrentFolder (Environment.GetFolderPath (Environment.SpecialFolder.Personal));
|
||||
|
||||
if (dialog.Run () == (int) ResponseType.Accept) {
|
||||
_pipelineOK = false;
|
||||
|
||||
if (_pipeline != null) {
|
||||
_pipeline.SetState (Gst.State.Null);
|
||||
_pipeline.Dispose ();
|
||||
}
|
||||
|
||||
_scale.Value = 0;
|
||||
|
||||
_pipeline = new Pipeline (string.Empty);
|
||||
|
||||
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'");
|
||||
if (sink == null)
|
||||
Console.WriteLine ("Unable to create element 'sink'");
|
||||
|
||||
_pipeline.Add (playbin);
|
||||
|
||||
sink.XwindowId = gdk_x11_drawable_get_xid (_da.GdkWindow.Handle);
|
||||
|
||||
playbin["video-sink"] = sink;
|
||||
playbin["uri"] = "file://" + dialog.Filename;
|
||||
|
||||
StateChangeReturn sret = _pipeline.SetState (Gst.State.Playing);
|
||||
|
||||
if (sret == StateChangeReturn.Async) {
|
||||
State state, pending;
|
||||
sret = _pipeline.GetState (out state, out pending, Clock.Second * 5);
|
||||
}
|
||||
|
||||
if (sret == StateChangeReturn.Success)
|
||||
_pipelineOK = true;
|
||||
else
|
||||
Console.WriteLine ("State change failed for {0} ({1})\n", dialog.Filename, sret);
|
||||
}
|
||||
|
||||
dialog.Destroy ();
|
||||
}
|
||||
|
||||
void ButtonPlayClicked (object sender, EventArgs args) {
|
||||
if ( (_pipeline != null) && _pipelineOK)
|
||||
_pipeline.SetState (Gst.State.Playing);
|
||||
}
|
||||
|
||||
void ButtonPauseClicked (object sender, EventArgs args) {
|
||||
if ( (_pipeline != null) && _pipelineOK)
|
||||
_pipeline.SetState (Gst.State.Paused);
|
||||
}
|
||||
|
||||
void ScaleValueChanged (object sender, EventArgs args) {
|
||||
if (_updatingScale)
|
||||
return;
|
||||
|
||||
long duration;
|
||||
Gst.Format fmt = Gst.Format.Time;
|
||||
|
||||
if ( (_pipeline != null) && _pipelineOK && _pipeline.QueryDuration (ref fmt, out duration)) {
|
||||
long pos = (long) (duration * _scale.Value);
|
||||
//Console.WriteLine ("Seek to {0}/{1} ({2}%)", pos, duration, _scale.Value);
|
||||
|
||||
_pipeline.Seek (Format.Time, SeekFlags.Flush, pos);
|
||||
}
|
||||
}
|
||||
|
||||
bool UpdatePos () {
|
||||
Gst.Format fmt = Gst.Format.Time;
|
||||
long duration, pos;
|
||||
if ( (_pipeline != null) && _pipelineOK &&
|
||||
_pipeline.QueryDuration (ref fmt, out duration) &&
|
||||
_pipeline.QueryPosition (ref fmt, out pos)) {
|
||||
_lbl.Text = string.Format ("{0} / {1}", TimeString (pos), TimeString (duration));
|
||||
|
||||
_updatingScale = true;
|
||||
_scale.Value = (double) pos / duration;
|
||||
_updatingScale = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
string TimeString (long t) {
|
||||
long secs = t / 1000000000;
|
||||
int mins = (int) (secs / 60);
|
||||
secs = secs - (mins * 60);
|
||||
|
||||
if (mins >= 60) {
|
||||
int hours = (int) (mins / 60);
|
||||
mins = mins - (hours * 60);
|
||||
|
||||
return string.Format ("{0}:{1:d2}:{2:d2}", hours, mins, secs);
|
||||
}
|
||||
|
||||
return string.Format ("{0}:{1:d2}", mins, secs);
|
||||
}
|
||||
|
||||
[DllImport ("libgdk-x11-2.0") ]
|
||||
static extern uint gdk_x11_drawable_get_xid (IntPtr handle);
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
TARGETS = playbin-player.exe decodebin-transcoder.exe helloworld.exe typefind.exe
|
||||
TARGETS = playbin-player.exe decodebin-transcoder.exe helloworld.exe typefind.exe metadata.exe gtk-video-player.exe
|
||||
DEBUGS = $(addsuffix .mdb, $(TARGETS))
|
||||
|
||||
all: $(TARGETS) link
|
||||
|
@ -28,6 +28,9 @@ metadata.exe: $(srcdir)/MetaData.cs $(assemblies)
|
|||
mp3launchparse.exe: $(srcdir)/MP3LaunchParse.cs $(assemblies)
|
||||
$(CSC) -out:$@ $(GLIBSHARP_LIBS) $(references) $(srcdir)/MP3LaunchParse.cs
|
||||
|
||||
gtk-video-player.exe: $(srcdir)/GtkVideoPlayer.cs $(assemblies)
|
||||
$(CSC) $(GLIBSHARP_LIBS) $(references) -pkg:gtk-sharp-2.0 $(srcdir)/GtkVideoPlayer.cs /out:gtk-video-player.exe
|
||||
|
||||
link:
|
||||
ln -sf $(top_builddir)/gstreamer-sharp/gstreamer-sharp.dll gstreamer-sharp.dll
|
||||
ln -sf $(top_builddir)/gstreamer-sharp/gstreamer-sharp.dll.config gstreamer-sharp.dll.config
|
||||
|
|
|
@ -1,161 +1,167 @@
|
|||
//
|
||||
// Authors
|
||||
// Khaled Mohammed (khaled.mohammed@gmail.com)
|
||||
//
|
||||
// (C) 2006
|
||||
//
|
||||
// Copyright (C) 2006 Khaled Mohammed <khaled.mohammed@gmail.com>
|
||||
// Copyright (C) 2008 Paul Burton <paulburton89@gmail.com>
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
using Gst;
|
||||
using System;
|
||||
|
||||
public class MetaData
|
||||
{
|
||||
public class MetaData {
|
||||
static Element pipeline = null;
|
||||
static Element source = null;
|
||||
|
||||
static Element pipeline = null;
|
||||
static Element source = null;
|
||||
static void PrintTag (TagList list, string tag) {
|
||||
uint count = list.GetTagSize (tag);
|
||||
|
||||
static void PrintTag( TagList list, string tag) {
|
||||
uint count = list.GetTagSize(tag);
|
||||
Console.WriteLine("Tags found = " + count);
|
||||
for(uint i =0; i < count; i++)
|
||||
{
|
||||
string str;
|
||||
if(Tag.GetGType(tag) == GLib.GType.String) {
|
||||
if(!list.GetStringIndex(tag, i, out str))
|
||||
Console.Error.WriteLine("g_assert_not_reached()???");
|
||||
} else {
|
||||
str = (String) list.GetValueIndex(tag, i).Val;
|
||||
}
|
||||
//Console.WriteLine ("Tags found = " + count);
|
||||
|
||||
if(i == 0)
|
||||
Console.WriteLine("{0}:\t {1}", Tag.GetNick(tag), str);
|
||||
else
|
||||
Console.WriteLine("\t{0}", str);
|
||||
}
|
||||
}
|
||||
for (uint i = 0; i < count; i++) {
|
||||
string str;
|
||||
|
||||
static bool MessageLoop(Element element, ref TagList tags)
|
||||
{
|
||||
Bus bus = element.Bus;
|
||||
bool done = false;
|
||||
try {
|
||||
str = list[tag, i].ToString ();
|
||||
} catch (Exception ex) {
|
||||
str = ex.Message;
|
||||
}
|
||||
|
||||
while(!done) {
|
||||
Message message = bus.Pop();
|
||||
if(message == null)
|
||||
break;
|
||||
if (i == 0)
|
||||
Console.WriteLine ("{0}: {1}", Tag.GetNick (tag).PadRight (25), str);
|
||||
else
|
||||
Console.WriteLine ("{0}{1}", string.Empty.PadRight (27), str);
|
||||
}
|
||||
}
|
||||
|
||||
switch(message.Type) {
|
||||
case MessageType.Error:
|
||||
string error;
|
||||
message.ParseError(out error);
|
||||
message.Dispose();
|
||||
return true;
|
||||
case MessageType.Eos:
|
||||
message.Dispose();
|
||||
return true;
|
||||
case MessageType.Tag: {
|
||||
TagList new_tags = new TagList();
|
||||
message.ParseTag(new_tags);
|
||||
if(tags != null) {
|
||||
tags = tags.Merge(new_tags, TagMergeMode.KeepAll);
|
||||
}
|
||||
else {
|
||||
tags = new_tags;
|
||||
}
|
||||
//tags.Foreach(PrintTag);
|
||||
//new_tags.Dispose();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
message.Dispose();
|
||||
}
|
||||
bus.Dispose();
|
||||
return true;
|
||||
}
|
||||
static bool MessageLoop (Element element, ref TagList tags) {
|
||||
Bus bus = element.Bus;
|
||||
bool done = false;
|
||||
|
||||
static void MakePipeline()
|
||||
{
|
||||
Element decodebin;
|
||||
while (!done) {
|
||||
Message message = bus.Pop ();
|
||||
|
||||
if(pipeline != null) {
|
||||
pipeline.Dispose();
|
||||
}
|
||||
if (message == null)
|
||||
break;
|
||||
|
||||
pipeline = new Pipeline(String.Empty);
|
||||
source = ElementFactory.Make("filesrc", "source");
|
||||
decodebin = ElementFactory.Make("decodebin", "decodebin");
|
||||
switch (message.Type) {
|
||||
case MessageType.Error:
|
||||
Enum error;
|
||||
string msg;
|
||||
message.ParseError (out error, out msg);
|
||||
message.Dispose ();
|
||||
return true;
|
||||
|
||||
if(pipeline == null) Console.Error.WriteLine("Pipeline count not be created");
|
||||
if(source == null) Console.Error.WriteLine("Element filesrc could not be created");
|
||||
if(decodebin == null) Console.Error.WriteLine("Element decodebin coult not be created");
|
||||
case MessageType.Eos:
|
||||
message.Dispose ();
|
||||
return true;
|
||||
|
||||
Bin bin = (Bin) pipeline;
|
||||
bin.AddMany(source, decodebin);
|
||||
if(!source.Link(decodebin))
|
||||
Console.Error.WriteLine("filesrc could not be linked with decodebin");
|
||||
decodebin.Dispose();
|
||||
}
|
||||
case MessageType.Tag:
|
||||
TagList new_tags;
|
||||
|
||||
public static void Main(string [] args)
|
||||
{
|
||||
Application.Init();
|
||||
message.ParseTag (out new_tags);
|
||||
|
||||
if(args.Length < 1)
|
||||
{
|
||||
Console.Error.WriteLine("Please give filenames to read metadata from\n\n");
|
||||
return;
|
||||
}
|
||||
if (tags != null) {
|
||||
tags = tags.Merge (new_tags, TagMergeMode.KeepAll);
|
||||
new_tags.Dispose ();
|
||||
} else
|
||||
tags = new_tags;
|
||||
|
||||
MakePipeline();
|
||||
break;
|
||||
|
||||
int i=-1;
|
||||
while(++i < args.Length)
|
||||
{
|
||||
State state, pending;
|
||||
TagList tags = null;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
string filename = args[i];
|
||||
source.SetProperty("location", filename);
|
||||
message.Dispose ();
|
||||
}
|
||||
|
||||
StateChangeReturn sret = pipeline.SetState(State.Paused);
|
||||
bus.Dispose ();
|
||||
return true;
|
||||
}
|
||||
|
||||
if(sret == StateChangeReturn.Async) {
|
||||
if(StateChangeReturn.Success != pipeline.GetState(out state, out pending, Clock.Second * 5)) {
|
||||
Console.Error.WriteLine("State change failed for {0}. Aborting\n", filename);
|
||||
break;
|
||||
}
|
||||
} else if(sret != StateChangeReturn.Success) {
|
||||
Console.Error.WriteLine("{0} - Could not read file\n", filename);
|
||||
continue;
|
||||
}
|
||||
static void MakePipeline () {
|
||||
Element decodebin;
|
||||
|
||||
if(!MessageLoop(pipeline, ref tags)) {
|
||||
Console.Error.WriteLine("Failed in message reading for {0}", args[i]);
|
||||
}
|
||||
if (pipeline != null)
|
||||
pipeline.Dispose ();
|
||||
|
||||
if(tags != null) {
|
||||
Console.WriteLine("Metadata for {0}:", args[i]);
|
||||
tags.Foreach(new TagForeachFunc(PrintTag));
|
||||
tags.Dispose();
|
||||
tags = null;
|
||||
} else Console.Error.WriteLine("No metadata found for {0}", args[0]);
|
||||
pipeline = new Pipeline (String.Empty);
|
||||
source = ElementFactory.Make ("filesrc", "source");
|
||||
decodebin = ElementFactory.Make ("decodebin", "decodebin");
|
||||
|
||||
sret = pipeline.SetState(State.Null);
|
||||
if (pipeline == null)
|
||||
Console.WriteLine ("Pipeline could not be created");
|
||||
if (source == null)
|
||||
Console.WriteLine ("Element filesrc could not be created");
|
||||
if (decodebin == null)
|
||||
Console.WriteLine ("Element decodebin could not be created");
|
||||
|
||||
if(StateChangeReturn.Async == sret) {
|
||||
if(StateChangeReturn.Failure == pipeline.GetState(out state, out pending, Clock.TimeNone)) {
|
||||
Console.Error.WriteLine("State change failed. Aborting");
|
||||
}
|
||||
}
|
||||
}
|
||||
Bin bin = (Bin) pipeline;
|
||||
bin.Add (source, decodebin);
|
||||
|
||||
if(pipeline != null)
|
||||
{
|
||||
pipeline.Dispose();
|
||||
}
|
||||
if (!source.Link (decodebin))
|
||||
Console.WriteLine ("filesrc could not be linked with decodebin");
|
||||
|
||||
}
|
||||
//decodebin.Dispose ();
|
||||
}
|
||||
|
||||
public static void Main (string [] args) {
|
||||
Application.Init ();
|
||||
|
||||
if (args.Length < 1) {
|
||||
Console.WriteLine ("Please give filenames to read metadata from\n\n");
|
||||
return;
|
||||
}
|
||||
|
||||
MakePipeline ();
|
||||
|
||||
int i = -1;
|
||||
while (++i < args.Length) {
|
||||
State state, pending;
|
||||
TagList tags = null;
|
||||
|
||||
string filename = args[i];
|
||||
|
||||
if (!File.Exists (filename)) {
|
||||
Console.WriteLine ("File {0} does not exist", filename);
|
||||
continue;
|
||||
}
|
||||
|
||||
source["location"] = filename;
|
||||
|
||||
StateChangeReturn sret = pipeline.SetState (State.Paused);
|
||||
|
||||
if (sret == StateChangeReturn.Async) {
|
||||
if (StateChangeReturn.Success != pipeline.GetState (out state, out pending, Clock.Second * 5)) {
|
||||
Console.WriteLine ("State change failed for {0}. Aborting\n", filename);
|
||||
break;
|
||||
}
|
||||
} else if (sret != StateChangeReturn.Success) {
|
||||
Console.WriteLine ("{0} - Could not read file ({1})\n", filename, sret);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!MessageLoop (pipeline, ref tags))
|
||||
Console.Error.WriteLine ("Failed in message reading for {0}", args[i]);
|
||||
|
||||
if (tags != null) {
|
||||
Console.WriteLine ("Metadata for {0}:", filename);
|
||||
|
||||
foreach (string tag in tags.Tags)
|
||||
PrintTag (tags, tag);
|
||||
tags.Dispose ();
|
||||
tags = null;
|
||||
} else
|
||||
Console.WriteLine ("No metadata found for {0}", args[0]);
|
||||
|
||||
sret = pipeline.SetState (State.Null);
|
||||
|
||||
if (StateChangeReturn.Async == sret) {
|
||||
if (StateChangeReturn.Failure == pipeline.GetState (out state, out pending, Clock.TimeNone))
|
||||
Console.WriteLine ("State change failed. Aborting");
|
||||
}
|
||||
}
|
||||
|
||||
if (pipeline != null)
|
||||
pipeline.Dispose ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue