--- /dev/null
+// Authors
+// Copyright (C) 2014 Stephan Sundermann <stephansundermann@gmail.com>
+
+using System;
+using Gst;
+using System.Runtime.InteropServices;
+
+namespace GstreamerSharp
+{
+ class Playback
+ {
+ // Functions below print the capabilities in a human-friendly format
+ static void PrintCaps (Caps caps, string pfx) {
+
+ if (caps == null)
+ return;
+
+ if (caps.IsAny) {
+ Console.WriteLine ("{0}ANY", pfx);
+ return;
+ }
+
+ if (caps.IsEmpty) {
+ Console.WriteLine ("{0}EMPTY", pfx);
+ return;
+ }
+
+ for (uint i = 0; i < caps.Size; i++) {
+ var structure = caps.GetStructure (i);
+
+ Console.WriteLine ("{0}{1}", pfx, structure.Name);
+ structure.Foreach ((field_id, value) => {
+ var ptr = g_quark_to_string (field_id);
+ var quark = GLib.Marshaller.Utf8PtrToString (ptr);
+ Console.WriteLine ("{0} {1}: {2}", pfx, quark, value.Val);
+ return true;
+ });
+ }
+ }
+
+ // Prints information about a Pad Template, including its Capabilities*/
+ static void PrintPadTemplateInformation (ElementFactory factory) {
+
+ Console.WriteLine ("Pad Templates for {0}:", factory.Name);
+ if (factory.NumPadTemplates == 0) {
+ Console.WriteLine (" none");
+ return;
+ }
+
+ var pads = factory.StaticPadTemplates;
+ foreach (var p in pads) {
+ var pad = (StaticPadTemplate) p;
+
+ if (pad.Direction == PadDirection.Src)
+ Console.WriteLine (" SRC template: '{0}'", pad.NameTemplate);
+ else if (pad.Direction == PadDirection.Sink)
+ Console.WriteLine (" SINK template: '{0}'", pad.NameTemplate);
+ else
+ Console.WriteLine (" UNKNOWN!!! template: '{0}'", pad.NameTemplate);
+
+ if (pad.Presence == PadPresence.Always)
+ Console.WriteLine (" Availability: Always");
+ else if (pad.Presence == PadPresence.Sometimes)
+ Console.WriteLine (" Availability: Sometimes");
+ else if (pad.Presence == PadPresence.Request) {
+ Console.WriteLine (" Availability: On request");
+ } else
+ Console.WriteLine (" Availability: UNKNOWN!!!");
+
+ if (pad.StaticCaps.String != null) {
+ Console.WriteLine (" Capabilities:");
+ PrintCaps (pad.StaticCaps.Get (), " ");
+ }
+
+ Console.WriteLine ();
+ }
+ }
+
+ // Shows the CURRENT capabilities of the requested pad in the given element */
+ static void PrintPadCapabilities (Element element, string padName) {
+
+ // Retrieve pad
+ var pad = element.GetStaticPad (padName);
+ if (pad == null) {
+ Console.WriteLine ("Could not retrieve pad '{0}'", padName);
+ return;
+ }
+
+ // Retrieve negotiated caps (or acceptable caps if negotiation is not finished yet)
+ var caps = pad.CurrentCaps;
+ if (caps == null)
+ caps = pad.Caps;
+
+ /* Print and free */
+ Console.WriteLine ("Caps for the {0} pad:", padName);
+ PrintCaps (caps, " ");
+ }
+
+ public static void Main (string[] args)
+ {
+ // Initialize Gstreamer
+ Gst.Application.Init(ref args);
+
+ // Create the element factories
+ var sourceFactory = ElementFactory.Find ("audiotestsrc");
+ var sinkFactory = ElementFactory.Find ("autoaudiosink");
+
+
+
+ if (sourceFactory == null || sinkFactory == null) {
+ Console.WriteLine ("Not all element factories could be created.");
+ return;
+ }
+
+ // Print information about the pad templates of these factories
+ PrintPadTemplateInformation (sourceFactory);
+ PrintPadTemplateInformation (sinkFactory);
+
+ // Ask the factories to instantiate actual elements
+ var source = sourceFactory.Create ("source");
+ var sink = sinkFactory.Create ("sink");
+
+ // Create the empty pipeline
+ var pipeline = new Pipeline ("test-pipeline");
+
+ if (pipeline == null || source == null || sink == null) {
+ Console.WriteLine ("Not all elements could be created.");
+ return;
+ }
+
+ // Build the pipeline
+ pipeline.Add (source, sink);
+ if (!source.Link (sink)) {
+ Console.WriteLine ("Elements could not be linked.");
+ return;
+ }
+
+ // Print initial negotiated caps (in NULL state)
+ Console.WriteLine ("In NULL state:");
+ PrintPadCapabilities (sink, "sink");
+
+ // Start playing
+ var ret = pipeline.SetState (State.Playing);
+ if (ret == StateChangeReturn.Failure) {
+ Console.WriteLine ("Unable to set the pipeline to the playing state (check the bus for error messages).");
+ }
+
+ // Wait until error, EOS or State Change
+ var bus = pipeline.Bus;
+ var terminate = false;
+
+ do {
+ var msg = bus.TimedPopFiltered (Constants.CLOCK_TIME_NONE, MessageType.Error | MessageType.Eos | MessageType.StateChanged);
+
+ // Parse message
+ if (msg != null) {
+ switch (msg.Type) {
+ case MessageType.Error:
+ string debug;
+ GLib.GException exc;
+ msg.ParseError (out exc, out debug);
+ Console.WriteLine ("Error received from element {0}: {1}", msg.Src.Name, exc.Message);
+ Console.WriteLine ("Debugging information: {0}", debug != null ? debug : "none");
+ terminate = true;
+ break;
+ case MessageType.Eos:
+ Console.WriteLine ("End-Of-Stream reached.\n");
+ terminate = true;
+ break;
+ case MessageType.StateChanged:
+ // We are only interested in state-changed messages from the pipeline
+ if (msg.Src == pipeline) {
+ State oldState, newState, pendingState;
+ msg.ParseStateChanged (out oldState, out newState, out pendingState);
+ Console.WriteLine ("Pipeline state changed from {0} to {1}:",
+ Element.StateGetName (oldState), Element.StateGetName (newState));
+ // Print the current capabilities of the sink element
+ PrintPadCapabilities (sink, "sink");
+ }
+ break;
+ default:
+ // We should not reach here because we only asked for ERRORs, EOS and STATE_CHANGED
+ Console.WriteLine ("Unexpected message received.");
+ break;
+ }
+ }
+ } while (!terminate);
+
+ // Free resources
+ pipeline.SetState (State.Null);
+ }
+
+ [DllImport ("libglib-2.0.so.0")]
+ static extern IntPtr g_quark_to_string (uint quark);
+ }
+}
\ No newline at end of file