/*
 * AppSink.cs: example of using the appsink element
 *
 * Authors:
 *   Maarten Bosmans <mkbosmans@gmail.com>
 *   William Lahti <wilahti@gmail.com>
 *
 * Copyright (C) 2009 Maarten Bosmans
 *
 */

using System;
using System.Runtime.InteropServices;
using Gst;
using GLib;

public class AppSinkDemo {
  static MainLoop loop;
  static Gst.App.AppSink appsink;
  static Pipeline pipeline;

  public static void Main (string[] args) {
    Application.Init();
    loop = new MainLoop();

	Gst.Element sink;
    pipeline = new Pipeline();

	/**/
    sink = appsink = new Gst.App.AppSink ("sink");
	appsink["emit-signals"] = true;
	appsink["max-buffers"] = (uint)2;
	appsink["drop"] = true;
	appsink["max-lateness"] = 250000000L; // a quarter second (ns)
			
	appsink.NewBuffer += HandleBuffer;
	/*/
	sink = ElementFactory.Make ("fakesink");
	//*/
    
	Element src = ElementFactory.Make ("videotestsrc");

    // Link the elements
    pipeline.Add (src, sink);
    src.Link(sink);

    // Connect the handlers
    pipeline.Bus.AddSignalWatch();
    pipeline.Bus.Message += MessageHandler;

    // Run, loop, run!
    pipeline.SetState (State.Playing);
    loop.Run();
    pipeline.SetState (State.Null);
  }

  [DllImport ("libgstreamer-0.10.dll") ]
  static extern void gst_mini_object_unref (IntPtr raw);
			
  static void HandleBuffer (object o, EventArgs e) {
	var buffer = appsink.PullBuffer();
	//gst_mini_object_unref(buffer.Handle);
	buffer.Dispose();
  }

  static void MessageHandler (object sender, MessageArgs args) {
    Message message = args.Message;
    string text = String.Format ("Message from {0}:  \t{1}", message.Src.Name, message.Type);
    switch (message.Type) {
      case MessageType.Error:
        Enum err;
        string msg;
        message.ParseError (out err, out msg);
        text += String.Format ("\t({0})", msg);
        break;
      case MessageType.StateChanged:
        State oldstate, newstate, pending;
        message.ParseStateChanged (out oldstate, out newstate, out pending);
        text += String.Format ("\t\t{0} -> {1}   ({2})", oldstate, newstate, pending);
        break;
      case MessageType.Eos:
        loop.Quit();
        break;
    }
    Console.WriteLine (text);
  }
}

