// #ifdef HAVE_CONFIG_H
// #include "config.h"
// #endif
// 
// #include <gst/gst.h>
// 
// #include <stdio.h>
// #include <string.h>
// #include <stdlib.h>
// 
// typedef struct _App App;
// 
// struct _App
// {
//   GstElement *playbin;
//   GstElement *textsink;
// 
//   GMainLoop *loop;
// };
// 
// App s_app;
// 
// static gboolean
// bus_message (GstBus * bus, GstMessage * message, App * app)
// {
//   GST_DEBUG ("got message %s",
//       gst_message_type_get_name (GST_MESSAGE_TYPE (message)));
// 
//   switch (GST_MESSAGE_TYPE (message)) {
//     case GST_MESSAGE_ERROR:
//     {
//       GError *gerror;
//       gchar *debug;
// 
//       gst_message_parse_error (message, &gerror, &debug);
//       gst_object_default_error (GST_MESSAGE_SRC (message), gerror, debug);
//       g_error_free (gerror);
//       g_free (debug);
// 
//       g_main_loop_quit (app->loop);
//       break;
//     }
//     case GST_MESSAGE_WARNING:
//     {
//       GError *gerror;
//       gchar *debug;
// 
//       gst_message_parse_warning (message, &gerror, &debug);
//       gst_object_default_error (GST_MESSAGE_SRC (message), gerror, debug);
//       g_error_free (gerror);
//       g_free (debug);
// 
//       g_main_loop_quit (app->loop);
//       break;
//     }
//     case GST_MESSAGE_EOS:
//       g_message ("received EOS");
//       g_main_loop_quit (app->loop);
//       break;
//     default:
//       break;
//   }
//   return TRUE;
// }
// 
// static void
// have_subtitle (GstElement * appsink, App * app)
// {
//   GstBuffer *buffer;
// 
//   /* get the buffer, we can also wakeup the mainloop to get the subtitle from
//    * appsink in the mainloop */
//   g_signal_emit_by_name (appsink, "pull-buffer", &buffer);
// 
//   if (buffer) {
//     guint8 *data;
//     guint size;
//     GstFormat format;
//     gint64 position;
//     GstClock *clock;
//     GstClockTime base_time, running_time;
// 
//     format = GST_FORMAT_TIME;
//     gst_element_query_position (appsink, &format, &position);
// 
//     clock = gst_element_get_clock (appsink);
//     base_time = gst_element_get_base_time (appsink);
// 
//     running_time = gst_clock_get_time (clock) - base_time;
// 
//     gst_object_unref (clock);
// 
//     g_message ("received a subtitle at position %" GST_TIME_FORMAT
//         ", running_time %" GST_TIME_FORMAT, GST_TIME_ARGS (position),
//         GST_TIME_ARGS (running_time));
// 
//     data = GST_BUFFER_DATA (buffer);
//     size = GST_BUFFER_SIZE (buffer);
// 
//     gst_util_dump_mem (data, size);
//   }
// }
// 
// int
// main (int argc, char *argv[])
// {
//   App *app = &s_app;
//   GstBus *bus;
// 
//   gst_init (&argc, &argv);
// 
//   if (argc < 2) {
//     g_print ("usage: %s <filename>\n", argv[0]);
//     return -1;
//   }
// 
//   /* create a mainloop to get messages */
//   app->loop = g_main_loop_new (NULL, TRUE);
// 
//   app->playbin = gst_element_factory_make ("playbin2", NULL);
//   g_assert (app->playbin);
// 
//   /* set appsink to get the subtitles */
//   app->textsink = gst_element_factory_make ("appsink", "subtitle_sink");
//   g_object_set (G_OBJECT (app->textsink), "emit-signals", TRUE, NULL);
//   g_object_set (G_OBJECT (app->textsink), "ts-offset", 0 * GST_SECOND, NULL);
//   g_signal_connect (app->textsink, "new-buffer", G_CALLBACK (have_subtitle), app);
// 
//   g_object_set (G_OBJECT (app->playbin), "flags", 0x45, NULL);
//   g_object_set (G_OBJECT (app->playbin), "text-sink", app->textsink, NULL);
//   g_object_set (G_OBJECT (app->textsink), "caps", gst_caps_from_string("text/x-pango-markup; text/plain; text/x-plain"), NULL);
// 
//   bus = gst_pipeline_get_bus (GST_PIPELINE (app->playbin));
// 
//   /* add watch for messages */
//   gst_bus_add_watch (bus, (GstBusFunc) bus_message, app);
// 
//   g_object_set (app->playbin, "uri", argv[1], NULL);
//   
//   if ( argc == 3 )
//   {
//     g_message ("using external subtitles %s", argv[2]);
//     g_object_set (app->playbin, "suburi", argv[2], NULL);
//   }
// 
//   /* go to playing and wait in a mainloop. */
//   gst_element_set_state (app->playbin, GST_STATE_PLAYING);
// 
//   /* this mainloop is stopped when we receive an error or EOS */
//   g_main_loop_run (app->loop);
// 
//   g_message ("stopping");
// 
//   gst_element_set_state (app->playbin, GST_STATE_NULL);
// 
//   gst_object_unref (bus);
//   g_main_loop_unref (app->loop);
// 
//   return 0;
// }
// 


/* GStreamer
 *
 * Copyright (C) 2009 Wim Taymans <wim.taymans@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <gst/gst.h>

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct _App App;

struct _App
{
  GstElement *playbin;
  GstElement *textsink;

  GMainLoop *loop;
};

App s_app;

static gboolean
bus_message (GstBus * bus, GstMessage * message, App * app)
{
  GST_DEBUG ("got message %s",
      gst_message_type_get_name (GST_MESSAGE_TYPE (message)));

  switch (GST_MESSAGE_TYPE (message)) {
    case GST_MESSAGE_ERROR:
    {
      GError *gerror;
      gchar *debug;

      gst_message_parse_error (message, &gerror, &debug);
      gst_object_default_error (GST_MESSAGE_SRC (message), gerror, debug);
      g_error_free (gerror);
      g_free (debug);

      g_main_loop_quit (app->loop);
      break;
    }
    case GST_MESSAGE_WARNING:
    {
//       GError *gerror;
//       gchar *debug;
//       gst_message_parse_warning (message, &gerror, &debug);
//       gst_object_default_error (GST_MESSAGE_SRC (message), gerror, debug);
//       g_error_free (gerror);
//       g_free (debug);

//       g_main_loop_quit (app->loop);
      break;
    }
    case GST_MESSAGE_EOS:
      g_message ("received EOS");
      g_main_loop_quit (app->loop);
      break;
		case GST_MESSAGE_ASYNC_DONE:
		{
			GstTagList *tags;
			gint i, active_idx, n_video = 0, n_audio = 0, n_text = 0;

			g_object_get (app->playbin, "n-video", &n_video, NULL);
			g_object_get (app->playbin, "n-audio", &n_audio, NULL);
			g_object_get (app->playbin, "n-text", &n_text, NULL);

			printf("eServiceMP3::async-done - %d video, %d audio, %d subtitle\n", n_video, n_audio, n_text);

			active_idx = 0;

			for (i = 0; i < n_audio; i++)
			{
				gchar *g_codec, *g_lang;
				g_lang = g_strdup_printf ("und");
				g_signal_emit_by_name (app->playbin, "get-audio-tags", i, &tags);
				if ( tags && gst_is_tag_list(tags) )
				{
					gst_tag_list_get_string(tags, GST_TAG_AUDIO_CODEC, &g_codec);
					gst_tag_list_get_string(tags, GST_TAG_LANGUAGE_CODE, &g_lang);
					gst_tag_list_free(tags);
				}
				printf("eServiceMP3::audio stream=%i codec=%s language=%s\n", i, g_codec, g_lang);
				g_free (g_lang);
				g_free (g_codec);
			}

			for (i = 0; i < n_text; i++)
			{
				gchar *g_lang;
				const gchar *g_type;
				g_signal_emit_by_name (app->playbin, "get-text-tags", i, &tags);

				g_lang = g_strdup_printf ("und");
				if ( tags && gst_is_tag_list(tags) )
				{
					gst_tag_list_get_string(tags, GST_TAG_LANGUAGE_CODE, &g_lang);
					gst_tag_list_free(tags);
				}
				
				GstPad* pad = 0;
				g_signal_emit_by_name (app->playbin, "get-text-pad", i, &pad);
				GstCaps* caps = gst_pad_get_negotiated_caps(pad);
	
				if (!caps)
					g_type = g_strdup_printf ("und");
				else
				{
					GstStructure* str = gst_caps_get_structure(caps, 0);
					g_type = gst_structure_get_name(str);
				}
				printf("eServiceMP3::subtitle stream=%i language=%s, type=%s\n", i, g_lang, g_type);
				g_free (g_lang);
			}
		}

    default:
      break;

  }
  return TRUE;
}

static void
have_subtitle (GstElement * appsink, App * app)
{
  GstBuffer *buffer;

  /* get the buffer, we can also wakeup the mainloop to get the subtitle from
   * appsink in the mainloop */
  g_signal_emit_by_name (appsink, "pull-buffer", &buffer);

  if (buffer) {
    guint8 *data;
    guint size;
    GstFormat format;
    gint64 position;
    GstClock *clock;
    GstClockTime base_time, running_time;

    format = GST_FORMAT_TIME;
    gst_element_query_position (appsink, &format, &position);

    clock = gst_element_get_clock (appsink);
    base_time = gst_element_get_base_time (appsink);

    running_time = gst_clock_get_time (clock) - base_time;

    gst_object_unref (clock);

    g_message ("received a subtitle at position %" GST_TIME_FORMAT
        ", running_time %" GST_TIME_FORMAT, GST_TIME_ARGS (position),
        GST_TIME_ARGS (running_time));

    data = GST_BUFFER_DATA (buffer);
    size = GST_BUFFER_SIZE (buffer);

    gst_util_dump_mem (data, size);
  }
}

static void gstCBsubtitleCAPS(GObject *obj, GParamSpec *pspec, App * app)
{
	printf("gstCBsubtitleCAPS:: signal::caps callback\n");
}

int
main (int argc, char *argv[])
{
	App *app = &s_app;
	GstBus *bus;

	gst_init (&argc, &argv);

	if (argc < 2) {
	g_print ("usage: %s <filename>\n", argv[0]);
	return -1;
	}

	/* create a mainloop to get messages */
	app->loop = g_main_loop_new (NULL, TRUE);

	app->playbin = gst_element_factory_make ("playbin2", NULL);
	g_assert (app->playbin);

	/* set appsink to get the subtitles */
	app->textsink = gst_element_factory_make ("appsink", "subtitle_sink");
	g_object_set (G_OBJECT (app->textsink), "emit-signals", TRUE, NULL);
	g_object_set (G_OBJECT (app->textsink), "ts-offset", 0 * GST_SECOND, NULL);
	g_signal_connect (app->textsink, "new-buffer", G_CALLBACK (have_subtitle),
	app);
	
	g_object_set (G_OBJECT (app->textsink), "caps", gst_caps_from_string("text/x-pango-markup; text/plain; video/x-raw-rgb"), NULL);

	g_object_set (G_OBJECT (app->playbin), "text-sink", app->textsink, NULL);

	GstPad *pad = gst_element_get_static_pad (app->textsink, "sink");
	g_signal_connect (pad, "notify::caps", G_CALLBACK (gstCBsubtitleCAPS), app);

	bus = gst_pipeline_get_bus (GST_PIPELINE (app->playbin));

	/* add watch for messages */
	gst_bus_add_watch (bus, (GstBusFunc) bus_message, app);

	/* set to read from appsrc */
	g_object_set (app->playbin, "uri", argv[1], NULL);

	/* go to playing and wait in a mainloop. */
	gst_element_set_state (app->playbin, GST_STATE_PLAYING);

	/* this mainloop is stopped when we receive an error or EOS */
	g_main_loop_run (app->loop);

	g_message ("stopping");

	gst_element_set_state (app->playbin, GST_STATE_NULL);

	gst_object_unref (bus);
	g_main_loop_unref (app->loop);

	return 0;
}

