/* GStreamer
 *
 * encoding.c: 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., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, 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, *caps;
  GstStructure *st;
  guint i, len;
  gchar *tmpstr, *desc;

  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++) {
    st = gst_caps_steal_structure (l, 0);
    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++) {
    st = gst_caps_steal_structure (l, 0);
    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++) {
    st = gst_caps_steal_structure (l, 0);
    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", NULL);
  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;
}
