#include <gst/gst.h>

#include <gst/rtsp-server/rtsp-server.h>

#define DEFAULT_RTSP_PORT "8554"

typedef struct
{
  GMainLoop *loop;
  GstRTSPServer *server;
  guint id;
} Application;

static void
media_prepared_cb (GstRTSPMedia * media)
{
  g_print("media prepared\n");
}

static GstRTSPFilterResult
remove_all_clients (GstRTSPServer *server,
    GstRTSPClient *client,
    gpointer user_data)
{
  return GST_RTSP_FILTER_REMOVE;
}

static gboolean
shutdown_cb (gpointer user_data)
{
  Application *app = user_data;

  g_print("shutdown\n");
  gst_rtsp_server_client_filter (app->server, remove_all_clients, NULL);
  g_object_unref (app->server);
  g_source_remove (app->id);

  g_print ("thread pool cleanup\n");
  gst_rtsp_thread_pool_cleanup ();
  g_print ("thread pool cleanup done\n");

  g_main_loop_quit (app->loop);

  return G_SOURCE_REMOVE;
}

static void
media_configure_cb (GstRTSPMediaFactory * factory,
    GstRTSPMedia * media,
    Application *app)
{
  g_print ("media configure\n");
  g_signal_connect (media, "prepared", G_CALLBACK (media_prepared_cb), app);
  g_idle_add (shutdown_cb, app);
}

int
main (int argc, char *argv[])
{
  Application app;
  GstRTSPMediaFactory *factory;
  GstRTSPMountPoints *mounts;

  gst_init (&argc, &argv);

  app.loop = g_main_loop_new (NULL, FALSE);
  app.server = gst_rtsp_server_new ();
  g_object_set (app.server, "service", DEFAULT_RTSP_PORT, NULL);

  /* A pipeline that waits 5s before pre-roll */
  factory = gst_rtsp_media_factory_new ();
  gst_rtsp_media_factory_set_launch (factory,
      "( videotestsrc timestamp-offset=5000000000 ! identity sync=true ! "
      "queue ! x264enc ! rtph264pay pt=96 name=pay0 )");
  g_signal_connect (factory, "media-configure",
      G_CALLBACK (media_configure_cb), &app);

  mounts = gst_rtsp_server_get_mount_points (app.server);
  gst_rtsp_mount_points_add_factory (mounts, "/test", factory);
  g_object_unref (mounts);

  g_print ("stream ready at rtsp://127.0.0.1:%s/test\n", DEFAULT_RTSP_PORT);
  app.id = gst_rtsp_server_attach (app.server, NULL);
  g_main_loop_run (app.loop);

  return 0;
}
