2006-07-13 Aaron Bockover <aaron@abock.org>

* gstreamer-sharp/BindingHelper.cs: Static helper class to assist
    in making element bindings (delegate manipulation/invocation)

    * gstreamer-sharp/DynamicSignal.cs: Updated DynamicSignalArgs so they
    can more easily be derived

    * gstreamer-sharp/Makefile.am: Updated build

    * sample/HelloWorld.cs: More cleaning

    * sample/Makefile.am:
    * sample/TypeFind.cs: Added typefind sample

    * gstreamer-sharp.mdp: Updated MonoDevelop project

    * gstreamer-sharp/plugins-base/DecodeBin.cs: Signal support rewritten
    to use BindingHelper/DynamicSignal

    * gstreamer-sharp/plugins-base/TypeFindElement.cs: New typefind
    element wrapper using BindingHelper/DynamicSignal

    * gstreamer-sharp/Element.custom: Fixed property getter/setter methods
    and added indexer wrapper for property lookup for syntax convenience



git-svn-id: svn://anonsvn.mono-project.com/source/branches/abock/gstreamer-sharp@62570 e3ebcda4-bce8-0310-ba0a-eca2169e7518
This commit is contained in:
Aaron Bockover 2006-07-13 16:16:51 +00:00
parent 0c76171b89
commit 73ed037fa4
11 changed files with 290 additions and 93 deletions

View file

@ -1,3 +1,29 @@
2006-07-13 Aaron Bockover <aaron@abock.org>
* gstreamer-sharp/BindingHelper.cs: Static helper class to assist
in making element bindings (delegate manipulation/invocation)
* gstreamer-sharp/DynamicSignal.cs: Updated DynamicSignalArgs so they
can more easily be derived
* gstreamer-sharp/Makefile.am: Updated build
* sample/HelloWorld.cs: More cleaning
* sample/Makefile.am:
* sample/TypeFind.cs: Added typefind sample
* gstreamer-sharp.mdp: Updated MonoDevelop project
* gstreamer-sharp/plugins-base/DecodeBin.cs: Signal support rewritten
to use BindingHelper/DynamicSignal
* gstreamer-sharp/plugins-base/TypeFindElement.cs: New typefind
element wrapper using BindingHelper/DynamicSignal
* gstreamer-sharp/Element.custom: Fixed property getter/setter methods
and added indexer wrapper for property lookup for syntax convenience
2006-07-12 Aaron Bockover <aaron@abock.org>
* sample/HelloWorld.cs: Cleaned up, works with new dynamic signal stuff

View file

@ -42,6 +42,9 @@
<File name="./gstreamer-sharp/glue/dynamicsignal.c" subtype="Code" buildaction="Nothing" />
<File name="./gstreamer-sharp/DynamicSignal.cs" subtype="Code" buildaction="Compile" />
<File name="./sample/HelloWorld.cs" subtype="Code" buildaction="Compile" />
<File name="./gstreamer-sharp/plugins-base/TypeFindElement.cs" subtype="Code" buildaction="Compile" />
<File name="./sample/TypeFind.cs" subtype="Code" buildaction="Compile" />
<File name="./gstreamer-sharp/BindingHelper.cs" subtype="Code" buildaction="Compile" />
</Contents>
<References />
</Project>

View file

@ -0,0 +1,52 @@
//
// BindingHelper.cs: Utility methods to make creating
// element bindings by hand an easier task
//
// Authors:
// Aaron Bockover (abockover@novell.com)
//
// (C) 2006 Novell, Inc.
//
using System;
using GLib;
namespace Gst
{
public static class BindingHelper
{
public static Delegate AddProxySignalDelegate(Element element, string signal,
GLib.DynamicSignalHandler baseHandler, Delegate existingHandler, Delegate addHandler)
{
if(existingHandler == null) {
element.Connect(signal, baseHandler);
}
return Delegate.Combine(existingHandler, addHandler);
}
public static Delegate RemoveProxySignalDelegate(Element element, string signal,
GLib.DynamicSignalHandler baseHandler, Delegate existingHandler, Delegate removeHandler)
{
Delegate temp_delegate = Delegate.Remove(existingHandler, removeHandler);
if(temp_delegate == null) {
element.Disconnect(signal, baseHandler);
}
return temp_delegate;
}
public static void InvokeProxySignalDelegate(Delegate raiseDelegate, Type type,
object o, GLib.DynamicSignalArgs args)
{
if(!type.IsSubclassOf(typeof(GLib.DynamicSignalArgs))) {
throw new ArgumentException("Args type must derive DynamicSignalArgs");
}
if(raiseDelegate != null) {
raiseDelegate.DynamicInvoke(new object [] { o,
Activator.CreateInstance(type, new object [] { args }) });
}
}
}
}

View file

@ -19,23 +19,29 @@ namespace GLib
{
private GLib.Object sender;
private object [] args;
internal DynamicSignalArgs(GLib.Object sender, object [] args)
public DynamicSignalArgs()
{
this.sender = sender;
this.args = args;
}
public DynamicSignalArgs(DynamicSignalArgs args)
{
Sender = args.Sender;
Args = args.Args;
}
public object this[int index] {
get { return Args[index]; }
}
public GLib.Object Sender {
get { return sender; }
internal set { sender = value; }
}
public object [] Args {
get { return args; }
internal set { args = value; }
}
}
@ -124,7 +130,10 @@ namespace GLib
DynamicSignalHandler handler = (DynamicSignalHandler)((GCHandle)userdata).Target;
if(handler != null) {
handler(gobject, new DynamicSignalArgs(gobject, args));
DynamicSignalArgs dargs = new DynamicSignalArgs();
dargs.Sender = gobject;
dargs.Args = args;
handler(gobject, dargs);
}
}

View file

@ -1,4 +1,9 @@
public object this[string property] {
get { return GetProperty(property).Val; }
set { SetProperty(property, value); }
}
public new GLib.Value GetProperty(string propertyName)
{
return base.GetProperty(propertyName);
@ -9,22 +14,29 @@
base.SetProperty(propertyName, value);
}
public void SetProperty(string propertyName, string value)
public void SetProperty(string propertyName, object value)
{
GLib.Value val = new GLib.Value(value);
base.SetProperty(propertyName, val);
base.SetProperty(propertyName, new GLib.Value(value));
}
public void SetProperty(string propertyName, double value)
public void SetProperty(string propertyName, string value)
{
GLib.Value val = new GLib.Value(value);
base.SetProperty(propertyName, val);
base.SetProperty(propertyName, new GLib.Value(value));
}
public void SetProperty(string propertyName, int value)
{
base.SetProperty(propertyName, new GLib.Value(value));
}
public void SetProperty(string propertyName, double value)
{
base.SetProperty(propertyName, new GLib.Value(value));
}
public void SetProperty(string propertyName, bool value)
{
GLib.Value val = new GLib.Value(value);
base.SetProperty(propertyName, val);
base.SetProperty(propertyName, new GLib.Value(value));
}
[DllImport("gstreamer-0.10.dll")]

View file

@ -38,12 +38,14 @@ clean-local:
sources = \
DynamicSignal.cs \
BindingHelper.cs \
Application.cs \
Version.cs \
AssemblyInfo.cs \
CommonTags.cs \
plugins-base/PlayBin.cs \
plugins-base/DecodeBin.cs
plugins-base/DecodeBin.cs \
plugins-base/TypeFindElement.cs
build_sources = $(addprefix $(srcdir)/, $(sources))

View file

@ -8,14 +8,18 @@
//
using System;
using System.Runtime.InteropServices;
using Gst;
namespace Gst
{
public delegate void NewDecodedPadHandler(object o, NewDecodedPadArgs args);
public class NewDecodedPadArgs : GLib.SignalArgs
public class NewDecodedPadArgs : GLib.DynamicSignalArgs
{
public NewDecodedPadArgs(GLib.DynamicSignalArgs args) : base(args)
{
}
public Gst.Pad Pad {
get { return (Gst.Pad)Args[0]; }
}
@ -27,84 +31,27 @@ namespace Gst
public class DecodeBin : Bin
{
private Delegate new_decoded_pad_delegate;
public DecodeBin(IntPtr raw) : base(raw)
{
}
}
[GLib.CDeclCallback]
private delegate void NewDecodedPadSignalDelegate(IntPtr arg0, IntPtr arg1, bool arg2, IntPtr gch);
private static void NewDecodedPadSignalCallback(IntPtr arg0, IntPtr arg1, bool arg2, IntPtr gch)
protected virtual void OnNewDecodedPad(object o, GLib.DynamicSignalArgs args)
{
GLib.Signal sig = ((GCHandle)gch).Target as GLib.Signal;
if(sig == null) {
throw new Exception("Unknown signal GC handle received " + gch);
}
Gst.NewDecodedPadArgs args = new Gst.NewDecodedPadArgs();
args.Args = new object[2];
args.Args[0] = GLib.Object.GetObject(arg1) as Gst.Pad;
args.Args[1] = arg2;
Gst.NewDecodedPadHandler handler = (Gst.NewDecodedPadHandler)sig.Handler;
handler(GLib.Object.GetObject(arg0), args);
BindingHelper.InvokeProxySignalDelegate(new_decoded_pad_delegate,
typeof(NewDecodedPadArgs), o, args);
}
[GLib.CDeclCallback]
private delegate void NewDecodedPadVMDelegate(IntPtr bin, IntPtr pad, bool last);
private static NewDecodedPadVMDelegate NewDecodedPadVMCallback;
private static void newdecodedpad_cb(IntPtr bin, IntPtr pad, bool last)
{
DecodeBin bin_managed = GLib.Object.GetObject(bin, false) as DecodeBin;
bin_managed.OnNewDecodedPad(GLib.Object.GetObject(pad) as Gst.Pad, last);
}
private static void OverrideNewDecodedPad(GLib.GType gtype)
{
if(NewDecodedPadVMCallback == null) {
NewDecodedPadVMCallback = new NewDecodedPadVMDelegate(newdecodedpad_cb);
}
OverrideVirtualMethod(gtype, "new-decoded-pad", NewDecodedPadVMCallback);
}
[GLib.DefaultSignalHandler(Type=typeof(Gst.DecodeBin), ConnectionMethod="OverrideNewDecodedPad")]
protected virtual void OnNewDecodedPad(Gst.Pad pad, bool last)
{
GLib.Value ret = GLib.Value.Empty;
GLib.ValueArray inst_and_params = new GLib.ValueArray(3);
GLib.Value [] vals = new GLib.Value[3];
vals[0] = new GLib.Value(this);
inst_and_params.Append(vals[0]);
vals[1] = new GLib.Value(pad);
inst_and_params.Append(vals[1]);
vals[2] = new GLib.Value(last);
inst_and_params.Append(vals[2]);
g_signal_chain_from_overridden(inst_and_params.ArrayPtr, ref ret);
foreach(GLib.Value v in vals) {
v.Dispose();
}
}
[GLib.Signal("new-decoded-pad")]
public event Gst.NewDecodedPadHandler NewDecodedPad {
public event NewDecodedPadHandler NewDecodedPad {
add {
GLib.Signal sig = GLib.Signal.Lookup(this, "new-decoded-pad",
new NewDecodedPadSignalDelegate(NewDecodedPadSignalCallback));
sig.AddDelegate(value);
new_decoded_pad_delegate = BindingHelper.AddProxySignalDelegate(this,
"new-decoded-pad", OnNewDecodedPad, new_decoded_pad_delegate, value);
}
remove {
GLib.Signal sig = GLib.Signal.Lookup(this, "new-decoded-pad",
new NewDecodedPadSignalDelegate(NewDecodedPadSignalCallback));
sig.RemoveDelegate(value);
new_decoded_pad_delegate = BindingHelper.RemoveProxySignalDelegate(this,
"new-decoded-pad", OnNewDecodedPad, new_decoded_pad_delegate, value);
}
}
}

View file

@ -0,0 +1,103 @@
//
// TypeFindElement.cs: typefind element binding
//
// Authors:
// Aaron Bockover (abockover@novell.com)
//
// (C) 2006 Novell, Inc.
//
using System;
namespace Gst
{
public delegate void HaveTypeHandler(object o, HaveTypeArgs args);
public class HaveTypeArgs : GLib.DynamicSignalArgs
{
public HaveTypeArgs(GLib.DynamicSignalArgs args) : base(args)
{
}
public uint Probability {
get { return (uint)Args[0]; }
}
public Gst.Caps Caps {
get { return (Gst.Caps)Args[1]; }
}
}
public class TypeFindElement : Element
{
private Delegate have_type_delegate;
public TypeFindElement(IntPtr raw) : base(raw)
{
}
public static TypeFindElement Make(string name)
{
return ElementFactory.Make("typefind", name) as TypeFindElement;
}
protected virtual void OnHaveType(object o, GLib.DynamicSignalArgs args)
{
BindingHelper.InvokeProxySignalDelegate(have_type_delegate, typeof(HaveTypeArgs), o, args);
}
public event HaveTypeHandler HaveType {
add {
have_type_delegate = BindingHelper.AddProxySignalDelegate(this, "have-type",
OnHaveType, have_type_delegate, value);
}
remove {
have_type_delegate = BindingHelper.RemoveProxySignalDelegate(this, "have-type",
OnHaveType, have_type_delegate, value);
}
}
[GLib.Property("caps")]
public Gst.Caps Caps {
get {
GLib.Value val = GetProperty("caps");
Gst.Caps caps = (Gst.Caps)val.Val;
val.Dispose();
return caps;
}
}
[GLib.Property("minimum")]
public uint Minimum {
get {
GLib.Value val = GetProperty("minimum");
uint ret = (uint)val.Val;
val.Dispose();
return ret;
}
set {
GLib.Value val = new GLib.Value(value);
SetProperty("minimum", val);
val.Dispose();
}
}
[GLib.Property("maximum")]
public uint Maximum {
get {
GLib.Value val = GetProperty("maximum");
uint ret = (uint)val.Val;
val.Dispose();
return ret;
}
set {
GLib.Value val = new GLib.Value(value);
SetProperty("maximum", val);
val.Dispose();
}
}
}
}

View file

@ -17,11 +17,8 @@ public class HelloWorld
Application.Init();
loop = new MainLoop();
if((pipeline = new Pipeline("audio-player")) == null) {
Console.WriteLine("Could not create audio player pipeline");
}
pipeline = new Pipeline("audio-player");
if((source = ElementFactory.Make("filesrc", "file-source")) == null) {
Console.WriteLine("Could not create file-source");
}
@ -32,7 +29,7 @@ public class HelloWorld
identity = ElementFactory.Make("identity", "identitye");
sink = ElementFactory.Make("alsasink", "alsa-output");
source.SetProperty("location", args[0]);
source["location"] = args[0];
Bin bin = (Bin) pipeline;
bin.Bus.AddWatch(new BusFunc(BusCall));

View file

@ -1,6 +1,8 @@
TARGETS = playbin-player.exe decodebin-transcoder.exe helloworld.exe
TARGETS = playbin-player.exe decodebin-transcoder.exe helloworld.exe typefind.exe
DEBUGS = $(addsuffix .mdb, $(TARGETS))
all: $(TARGETS) link
assemblies=$(top_builddir)/gstreamer-sharp/gstreamer-sharp.dll
references=$(addprefix /r:, $(assemblies))
@ -14,9 +16,16 @@ decodebin-transcoder.exe: $(srcdir)/DecodeBinTranscoder.cs $(assemblies)
helloworld.exe: $(srcdir)/HelloWorld.cs $(assemblies)
$(CSC) -out:$@ $(GLIBSHARP_LIBS) $(references) $(srcdir)/HelloWorld.cs
typefind.exe: $(srcdir)/TypeFind.cs $(assemblies)
$(CSC) -out:$@ $(GLIBSHARP_LIBS) $(references) $(srcdir)/TypeFind.cs
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
noinst_SCRIPTS = $(TARGETS)
CLEANFILES = $(TARGETS) $(DEBUGS)
CLEANFILES = $(TARGETS) $(DEBUGS) gstreamer-sharp.dll*
MAINTAINERCLEANFILES = Makefile.in
EXTRA_DIST = \

37
sample/TypeFind.cs Normal file
View file

@ -0,0 +1,37 @@
using System;
using Gst;
public static class GstTypefindTest
{
private static TypeFindElement typefind;
public static void Main(string [] args)
{
Application.Init();
Pipeline pipeline = new Pipeline("pipeline");
Element source = ElementFactory.Make("filesrc", "source");
typefind = TypeFindElement.Make("typefind");
Element sink = ElementFactory.Make("fakesink", "sink");
source.SetProperty("location", args[0]);
typefind.HaveType += OnHaveType;
pipeline.AddMany(source, typefind, sink);
source.Link(typefind);
typefind.Link(sink);
pipeline.SetState(State.Paused);
pipeline.SetState(State.Null);
pipeline.Dispose();
}
private static void OnHaveType(object o, HaveTypeArgs args)
{
args.Caps.Refcount++;
Console.WriteLine("MimeType: {0}, {1}", args.Caps, typefind.Caps);
}
}