gstreamer/sample/DecodeBinTranscoder.cs
Michael Dominic K 6566359e35 2006-06-04 Michael Dominic K. <michaldominik@gmail.com>
* sample/DecodeBinTranscoder.cs: Fixing ambigious cast.

	* gstreamer-sharp/glue/clock.c:
	* gstreamer-sharp/Clock.custom: Changing the gint64 to guint64 and
	long to ulong respectively. The clocktime (GstClockTime) is measured
	in nanoseconds as unsigned long inside GStreamer. 
	This is introducing a small schizophrenia since some functions (such
	as queries, seeks) take signed long (-1 to mark infinity or error).
	This is the expected Gst behaviour.
	Just sticking silently to long (instead of ulong) will bork us 	sooner
	or later, especially for custom-build low level routines/elements.
	Comments welcome.



git-svn-id: svn://anonsvn.mono-project.com/source/branches/abock/gstreamer-sharp@61438 e3ebcda4-bce8-0310-ba0a-eca2169e7518
2006-06-04 13:11:24 +00:00

196 lines
5.3 KiB
C#

//
// DecodeBinTranscoder.cs: sample transcoder using DecodeBin binding
//
// Authors:
// Aaron Bockover (abockover@novell.com)
//
// (C) 2006 Novell, Inc.
//
using System;
using Gst;
public delegate void ErrorHandler(object o, ErrorArgs args);
public delegate void ProgressHandler(object o, ProgressArgs args);
public class ErrorArgs : EventArgs
{
public string Error;
}
public class ProgressArgs : EventArgs
{
public long Duration;
public long Position;
}
public class DecodeBinTranscoder : IDisposable
{
private Pipeline pipeline;
private Element filesrc;
private Element filesink;
private Element audioconvert;
private Element encoder;
private DecodeBin decodebin;
private uint progress_timeout;
public event EventHandler Finished;
public event ErrorHandler Error;
public event ProgressHandler Progress;
public DecodeBinTranscoder()
{
ConstructPipeline();
}
public void Transcode(string inputFile, string outputFile)
{
filesrc.SetProperty("location", inputFile);
filesink.SetProperty("location", outputFile);
pipeline.SetState(State.Playing);
progress_timeout = GLib.Timeout.Add(250, OnProgressTimeout);
}
public void Dispose()
{
pipeline.Dispose();
}
protected virtual void OnFinished()
{
EventHandler handler = Finished;
if(handler != null) {
handler(this, new EventArgs());
}
}
protected virtual void OnError(string error)
{
ErrorHandler handler = Error;
if(handler != null) {
ErrorArgs args = new ErrorArgs();
args.Error = error;
handler(this, args);
}
}
protected virtual void OnProgress(long position, long duration)
{
ProgressHandler handler = Progress;
if(handler != null) {
ProgressArgs args = new ProgressArgs();
args.Position = position;
args.Duration = duration;
handler(this, args);
}
}
private void ConstructPipeline()
{
pipeline = new Pipeline("pipeline");
filesrc = ElementFactory.Make("filesrc", "filesrc");
filesink = ElementFactory.Make("filesink", "filesink");
audioconvert = ElementFactory.Make("audioconvert", "audioconvert");
encoder = ElementFactory.Make("wavenc", "wavenc");
decodebin = ElementFactory.Make("decodebin", "decodebin") as DecodeBin;
decodebin.NewDecodedPad += OnNewDecodedPad;
pipeline.AddMany(filesrc, decodebin, audioconvert, encoder, filesink);
filesrc.Link(decodebin);
audioconvert.Link(encoder);
encoder.Link(filesink);
pipeline.Bus.AddWatch(new BusFunc(OnBusMessage));
}
private void OnNewDecodedPad(object o, NewDecodedPadArgs args)
{
Pad sinkpad = audioconvert.GetPad("sink");
if(sinkpad.IsLinked) {
return;
}
Caps caps = args.Pad.Caps;
Structure structure = caps.GetStructure(0);
if(!structure.Name.StartsWith("audio")) {
return;
}
args.Pad.Link(sinkpad);
}
private bool OnBusMessage(Bus bus, Message message)
{
switch(message.Type) {
case MessageType.Error:
string error;
message.ParseError(out error);
GLib.Source.Remove(progress_timeout);
OnError(error);
break;
case MessageType.Eos:
pipeline.SetState(State.Null);
GLib.Source.Remove(progress_timeout);
OnFinished();
break;
}
return true;
}
private bool OnProgressTimeout()
{
long duration, position;
if(pipeline.QueryDuration(Gst.Format.Time, out duration) &&
encoder.QueryPosition(Gst.Format.Time, out position)) {
OnProgress(position, duration);
}
return true;
}
private static GLib.MainLoop loop;
public static void Main(string [] args)
{
if(args.Length < 2) {
Console.WriteLine("Usage: mono decodebin-transcoder.exe <input-file> <output-file>");
return;
}
Gst.Application.Init();
loop = new GLib.MainLoop();
DecodeBinTranscoder transcoder = new DecodeBinTranscoder();
transcoder.Error += delegate(object o, ErrorArgs args) {
Console.WriteLine("Error: {0}", args.Error);
transcoder.Dispose();
loop.Quit();
};
transcoder.Finished += delegate {
Console.WriteLine("\nFinished");
transcoder.Dispose();
loop.Quit();
};
transcoder.Progress += delegate(object o, ProgressArgs args) {
Console.Write("\rEncoding: {0} / {1} ({2:00.00}%) ",
new TimeSpan((args.Position / (long) Clock.GstSecond) * TimeSpan.TicksPerSecond),
new TimeSpan((args.Duration / (long) Clock.GstSecond) * TimeSpan.TicksPerSecond),
((double)args.Position / (double)args.Duration) * 100.0);
};
transcoder.Transcode(args[0], args[1]);
loop.Run();
}
}