2014-08-05 21:05:32 +00:00
|
|
|
// 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);
|
|
|
|
}
|
|
|
|
|
2018-05-21 08:34:13 +00:00
|
|
|
[DllImport ("libglib-2.0.dll")]
|
2014-08-05 21:05:32 +00:00
|
|
|
static extern IntPtr g_quark_to_string (uint quark);
|
|
|
|
}
|
|
|
|
}
|