/* Example application for using GstProfile and encodebin
 * Copyright (C) 2009 Edward Hervey <edward.hervey@collabora.co.uk>
 *
 * 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 <stdlib.h>
#include <glib.h>
#include <glib/gprintf.h>
#include <gst/gst.h>
#include <gst/pbutils/pbutils.h>
#include <gst/pbutils/encoding-profile.h>
#include "gstcapslist.h"

static gboolean silent = FALSE;

static void
list_codecs (void)
{
  GstCaps *l;
  GstCaps *caps;
  guint i, len;

  caps = gst_caps_new_empty ();

  g_print ("Available container formats:\n");
  l = gst_caps_list_container_formats (GST_RANK_NONE);
  len = gst_caps_get_size (l);
  for (i = 0; i < len; i++) {
    GstStructure *st = gst_caps_steal_structure (l, 0);
    gchar *tmpstr, *desc;

    gst_caps_append_structure (caps, st);

    tmpstr = gst_caps_to_string (caps);
    desc = gst_pb_utils_get_codec_description (caps);
    g_print ("  %s - %s\n", desc, tmpstr);
    g_free (tmpstr);
    if (desc)
      g_free (desc);
    gst_caps_remove_structure (caps, 0);
  }
  g_print ("\n");
  gst_caps_unref (l);

  g_print ("Available video codecs:\n");
  l = gst_caps_list_video_encoding_formats (GST_RANK_NONE);
  len = gst_caps_get_size (l);
  for (i = 0; i < len; i++) {
    GstStructure *st = gst_caps_steal_structure (l, 0);
    gchar *tmpstr, *desc;

    gst_caps_append_structure (caps, st);

    tmpstr = gst_caps_to_string (caps);
    desc = gst_pb_utils_get_codec_description (caps);
    g_print ("  %s - %s\n", desc, tmpstr);
    g_free (tmpstr);
    if (desc)
      g_free (desc);
    gst_caps_remove_structure (caps, 0);
  }
  g_print ("\n");
  gst_caps_unref (l);

  g_print ("Available audio codecs:\n");
  l = gst_caps_list_audio_encoding_formats (GST_RANK_NONE);
  len = gst_caps_get_size (l);
  for (i = 0; i < len; i++) {
    GstStructure *st = gst_caps_steal_structure (l, 0);
    gchar *tmpstr, *desc;

    gst_caps_append_structure (caps, st);

    tmpstr = gst_caps_to_string (caps);
    desc = gst_pb_utils_get_codec_description (caps);
    g_print ("  %s - %s\n", desc, tmpstr);
    g_free (tmpstr);
    if (desc)
      g_free (desc);
    gst_caps_remove_structure (caps, 0);
  }
  g_print ("\n");
  gst_caps_unref (l);

  gst_caps_unref (caps);
}

static gchar *
generate_filename (const GstCaps * container, const GstCaps * vcodec,
    const GstCaps * acodec)
{
  gchar *a, *b, *c;
  gchar *res = NULL;
  guint i;

  a = gst_pb_utils_get_codec_description (container);
  b = gst_pb_utils_get_codec_description (vcodec);
  c = gst_pb_utils_get_codec_description (acodec);

  if (!a)
    a = g_strdup_printf ("%.10s",
        g_uri_escape_string (gst_caps_to_string (container), NULL, FALSE));
  if (!b)
    b = g_strdup_printf ("%.10s",
        g_uri_escape_string (gst_caps_to_string (vcodec), NULL, FALSE));
  if (!c)
    c = g_strdup_printf ("%.10s",
        g_uri_escape_string (gst_caps_to_string (acodec), NULL, FALSE));

  for (i = 0; i < 256 && res == NULL; i++) {
    res = g_strdup_printf ("%s-%s-%s-%d.file", a, b, c, i);
    if (g_file_test (res, G_FILE_TEST_EXISTS)) {
      g_free (res);
      res = NULL;
    }
  }
  /* Make sure file doesn't already exist */

  g_free (a);
  g_free (b);
  g_free (c);

  return res;
}

static GstEncodingProfile *
create_profile (GstCaps * cf, GstCaps * vf, GstCaps * af)
{
  GstEncodingContainerProfile *cprof = NULL;

  cprof =
      gst_encoding_container_profile_new ((gchar *) "test-application-profile",
      NULL, cf, NULL);

  if (vf)
    gst_encoding_container_profile_add_profile (cprof,
        (GstEncodingProfile *) gst_encoding_video_profile_new (vf,
            NULL, NULL, 0));
  if (af)
    gst_encoding_container_profile_add_profile (cprof, (GstEncodingProfile *)
        gst_encoding_audio_profile_new (af, NULL, NULL, 0));

  /* Let's print out some info */
  if (!silent) {
    gchar *desc = gst_pb_utils_get_codec_description (cf);
    gchar *cd = gst_caps_to_string (cf);
    g_print ("Encoding parameters\n");
    g_print ("  Container format : %s (%s)\n", desc, cd);
    g_free (desc);
    g_free (cd);
    if (vf) {
      desc = gst_pb_utils_get_codec_description (vf);
      cd = gst_caps_to_string (vf);
      g_print ("  Video format : %s (%s)\n", desc, cd);
      g_free (desc);
      g_free (cd);
    }
    if (af) {
      desc = gst_pb_utils_get_codec_description (af);
      cd = gst_caps_to_string (af);
      g_print ("  Audio format : %s (%s)\n", desc, cd);
      g_free (desc);
      g_free (cd);
    }
  }

  return (GstEncodingProfile *) cprof;
}

static GstEncodingProfile *
create_profile_from_string (gchar * format, gchar * vformat, gchar * aformat)
{
  GstEncodingProfile *prof = NULL;
  GstCaps *cf = NULL, *vf = NULL, *af = NULL;

  if (format)
    cf = gst_caps_from_string (format);
  if (vformat)
    vf = gst_caps_from_string (vformat);
  if (aformat)
    af = gst_caps_from_string (aformat);

  if (G_UNLIKELY ((vformat && (vf == NULL)) || (aformat && (af == NULL))))
    goto beach;

  prof = create_profile (cf, vf, af);

beach:
  if (cf)
    gst_caps_unref (cf);
  if (vf)
    gst_caps_unref (vf);
  if (af)
    gst_caps_unref (af);

  return prof;
}

static void
pad_added_cb (GstElement * uridecodebin, GstPad * pad, GstElement * encodebin)
{
  GstPad *sinkpad;

  sinkpad = gst_element_get_compatible_pad (encodebin, pad, NULL);

  if (sinkpad == NULL) {
    GstCaps *caps;

    /* Ask encodebin for a compatible pad */
    caps = gst_pad_query_caps (pad, NULL);
    g_signal_emit_by_name (encodebin, "request-pad", caps, &sinkpad);
    if (caps)
      gst_caps_unref (caps);
  }
  if (sinkpad == NULL) {
    g_print ("Couldn't get an encoding channel for pad %s:%s\n",
        GST_DEBUG_PAD_NAME (pad));
    return;
  }

  if (G_UNLIKELY (gst_pad_link (pad, sinkpad) != GST_PAD_LINK_OK)) {
    g_print ("Couldn't link pads\n");
  }

  return;
}

static gboolean
autoplug_continue_cb (GstElement * uridecodebin, GstPad * somepad,
    GstCaps * caps, GstElement * encodebin)
{
  GstPad *sinkpad;

  g_signal_emit_by_name (encodebin, "request-pad", caps, &sinkpad);

  if (sinkpad == NULL)
    return TRUE;

  return FALSE;
}

static void
bus_message_cb (GstBus * bus, GstMessage * message, GMainLoop * mainloop)
{
  switch (GST_MESSAGE_TYPE (message)) {
    case GST_MESSAGE_ERROR:
      g_print ("ERROR\n");
      gst_bus_set_flushing (bus, TRUE);
      g_main_loop_quit (mainloop);
      break;
    case GST_MESSAGE_EOS:
      g_print ("Done\n");
      g_main_loop_quit (mainloop);
      break;
    default:
      break;
  }
}

static void
transcode_file (gchar * uri, gchar * outputuri, GstEncodingProfile * prof)
{
  GstElement *pipeline;
  GstElement *src;
  GstElement *ebin;
  GstElement *sink;
  GstBus *bus;
  GstCaps *profilecaps, *rescaps;
  GMainLoop *mainloop;

  g_print (" Input URI  : %s\n", uri);
  g_print (" Output URI : %s\n", outputuri);

  sink = gst_element_make_from_uri (GST_URI_SINK, outputuri, "sink");
  if (G_UNLIKELY (sink == NULL)) {
    g_print ("Can't create output sink, most likely invalid output URI !\n");
    return;
  }

  src = gst_element_factory_make ("uridecodebin", NULL);
  if (G_UNLIKELY (src == NULL)) {
    g_print ("Can't create uridecodebin for input URI, aborting!\n");
    return;
  }

  /* Figure out the streams that can be passed as-is to encodebin */
  g_object_get (src, "caps", &rescaps, NULL);
  rescaps = gst_caps_copy (rescaps);
  profilecaps = gst_encoding_profile_get_input_caps (prof);
  gst_caps_append (rescaps, profilecaps);

  /* Set properties */
  g_object_set (src, "uri", uri, "caps", rescaps, NULL);

  ebin = gst_element_factory_make ("encodebin", NULL);
  g_object_set (ebin, "profile", prof, NULL);

  g_signal_connect (src, "autoplug-continue", G_CALLBACK (autoplug_continue_cb),
      ebin);
  g_signal_connect (src, "pad-added", G_CALLBACK (pad_added_cb), ebin);

  pipeline = gst_pipeline_new ("encoding-pipeline");

  gst_bin_add_many (GST_BIN (pipeline), src, ebin, sink, NULL);

  gst_element_link (ebin, sink);

  mainloop = g_main_loop_new (NULL, FALSE);

  bus = gst_pipeline_get_bus ((GstPipeline *) pipeline);
  gst_bus_add_signal_watch (bus);
  g_signal_connect (bus, "message", G_CALLBACK (bus_message_cb), mainloop);

  if (gst_element_set_state (pipeline,
          GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
    g_print ("Failed to start the encoding\n");
    return;
  }

  g_main_loop_run (mainloop);

  gst_element_set_state (pipeline, GST_STATE_NULL);
  gst_object_unref (pipeline);
}

static gchar *
ensure_uri (gchar * location)
{
  gchar *res;
  gchar *path;

  if (gst_uri_is_valid (location))
    return g_strdup (location);

  if (!g_path_is_absolute (location)) {
    gchar *cur_dir;
    cur_dir = g_get_current_dir ();
    path = g_build_filename (cur_dir, location, NULL);
    g_free (cur_dir);
  } else
    path = g_strdup (location);

  res = g_filename_to_uri (path, NULL, NULL);
  g_free (path);

  return res;
}

int
main (int argc, char **argv)
{
  GError *err = NULL;
  gchar *outputuri = NULL;
  gchar *format = NULL;
  gchar *aformat = NULL;
  gchar *vformat = NULL;
  gboolean allmissing = FALSE;
  gboolean listcodecs = FALSE;
  GOptionEntry options[] = {
    {"silent", 's', 0, G_OPTION_ARG_NONE, &silent,
        "Don't output the information structure", NULL},
    {"outputuri", 'o', 0, G_OPTION_ARG_STRING, &outputuri,
        "URI to encode to", "URI (<protocol>://<location>)"},
    {"format", 'f', 0, G_OPTION_ARG_STRING, &format,
        "Container format", "<GstCaps>"},
    {"vformat", 'v', 0, G_OPTION_ARG_STRING, &vformat,
        "Video format", "<GstCaps>"},
    {"aformat", 'a', 0, G_OPTION_ARG_STRING, &aformat,
        "Audio format", "<GstCaps>"},
    {"allmissing", 'm', 0, G_OPTION_ARG_NONE, &allmissing,
        "encode to all matching format/codec that aren't specified", NULL},
    {"list-codecs", 'l', 0, G_OPTION_ARG_NONE, &listcodecs,
        "list all available codecs and container formats", NULL},
    {NULL}
  };
  GOptionContext *ctx;
  GstEncodingProfile *prof;
  gchar *inputuri;

  ctx = g_option_context_new ("- encode URIs with GstProfile and encodebin");
  g_option_context_add_main_entries (ctx, options, NULL);
  g_option_context_add_group (ctx, gst_init_get_option_group ());

  if (!g_option_context_parse (ctx, &argc, &argv, &err)) {
    g_print ("Error initializing: %s\n", err->message);
    exit (1);
  }

  if (listcodecs) {
    list_codecs ();
    g_option_context_free (ctx);
    exit (0);
  }

  if (outputuri == NULL || argc != 2) {
    g_print ("%s", g_option_context_get_help (ctx, TRUE, NULL));
    g_option_context_free (ctx);
    exit (-1);
  }

  g_option_context_free (ctx);

  /* Fixup outputuri to be a URI */
  inputuri = ensure_uri (argv[1]);
  outputuri = ensure_uri (outputuri);

  if (allmissing) {
    GList *muxers;
    GstCaps *formats = NULL;
    GstCaps *vformats = NULL;
    GstCaps *aformats = NULL;
    guint f, v, a, flen, vlen, alen;

    if (!format)
      formats = gst_caps_list_container_formats (GST_RANK_NONE);
    else
      formats = gst_caps_from_string (format);

    if (!vformat)
      vformats = gst_caps_list_video_encoding_formats (GST_RANK_NONE);
    else
      vformats = gst_caps_from_string (vformat);

    if (!aformat)
      aformats = gst_caps_list_audio_encoding_formats (GST_RANK_NONE);
    else
      aformats = gst_caps_from_string (aformat);
    muxers =
        gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_MUXER,
        GST_RANK_NONE);

    flen = gst_caps_get_size (formats);

    for (f = 0; f < flen; f++) {
      GstCaps *container =
          gst_caps_new_full (gst_caps_steal_structure (formats, 0), NULL);
      GstCaps *compatv =
          gst_caps_list_compatible_codecs (container, vformats, muxers);
      GstCaps *compata =
          gst_caps_list_compatible_codecs (container, aformats, muxers);

      vlen = gst_caps_get_size (compatv);
      alen = gst_caps_get_size (compata);


      for (v = 0; v < vlen; v++) {
        GstCaps *vcodec =
            gst_caps_new_full (gst_structure_copy (gst_caps_get_structure
                (compatv, v)), NULL);
        for (a = 0; a < alen; a++) {
          GstCaps *acodec =
              gst_caps_new_full (gst_structure_copy (gst_caps_get_structure
                  (compata, a)), NULL);

          prof =
              create_profile ((GstCaps *) container, (GstCaps *) vcodec,
              (GstCaps *) acodec);
          if (G_UNLIKELY (prof == NULL)) {
            g_print ("Wrong arguments\n");
            break;
          }
          outputuri =
              ensure_uri (generate_filename (container, vcodec, acodec));
          transcode_file (inputuri, outputuri, prof);
          gst_encoding_profile_unref (prof);

          gst_caps_unref (acodec);
        }
        gst_caps_unref (vcodec);
      }
      gst_caps_unref (container);
    }

  } else {

    /* Create the profile */
    prof = create_profile_from_string (format, vformat, aformat);
    if (G_UNLIKELY (prof == NULL)) {
      g_print ("Encoding arguments are not valid !\n");
      return 1;
    }

    /* Transcode file */
    transcode_file (inputuri, outputuri, prof);

    /* cleanup */
    gst_encoding_profile_unref (prof);

  }
  return 0;
}
