/* GStreamer
 * Copyright (C) <2011> Sebastian Dröge <sebastian.droege@collabora.co.uk>
 * Copyright (C) <2011> Vincent Penquerch <vincent.penquerch@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 "gstplaysinkconvertbin.h"

#include <gst/pbutils/pbutils.h>
#include <gst/gst-i18n-plugin.h>

GST_DEBUG_CATEGORY_STATIC (gst_play_sink_convert_bin_debug);
#define GST_CAT_DEFAULT gst_play_sink_convert_bin_debug

#define parent_class gst_play_sink_convert_bin_parent_class

static void gst_play_sink_convert_bin_sink_setcaps (GstPlaySinkConvertBin *
    self, GstCaps * caps);

G_DEFINE_TYPE (GstPlaySinkConvertBin, gst_play_sink_convert_bin, GST_TYPE_BIN);

static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS_ANY);

static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS_ANY);

static gboolean
is_raw_caps (GstCaps * caps, gboolean audio)
{
  gint i, n;
  GstStructure *s;
  const gchar *name;
  const gchar *prefix = audio ? "audio/x-raw" : "video/x-raw";

  n = gst_caps_get_size (caps);
  for (i = 0; i < n; i++) {
    s = gst_caps_get_structure (caps, i);
    name = gst_structure_get_name (s);
    if (g_str_equal (name, prefix))
      return TRUE;
  }

  return FALSE;
}

static void
gst_play_sink_convert_bin_post_missing_element_message (GstPlaySinkConvertBin *
    self, const gchar * name)
{
  GstMessage *msg;

  msg = gst_missing_element_message_new (GST_ELEMENT_CAST (self), name);
  gst_element_post_message (GST_ELEMENT_CAST (self), msg);
}

void
gst_play_sink_convert_bin_add_conversion_element (GstPlaySinkConvertBin * self,
    GstElement * el)
{
  self->conversion_elements = g_list_append (self->conversion_elements, el);
  gst_bin_add (GST_BIN (self), gst_object_ref (el));
}

GstElement *
gst_play_sink_convert_bin_add_conversion_element_factory (GstPlaySinkConvertBin
    * self, const char *factory, const char *name)
{
  GstElement *el;

  el = gst_element_factory_make (factory, name);
  if (el == NULL) {
    gst_play_sink_convert_bin_post_missing_element_message (self, factory);
    GST_ELEMENT_WARNING (self, CORE, MISSING_PLUGIN,
        (_("Missing element '%s' - check your GStreamer installation."),
            factory),
        (self->audio ? "audio rendering might fail" :
            "video rendering might fail"));
  } else {
    gst_play_sink_convert_bin_add_conversion_element (self, el);
  }
  return el;
}

void
gst_play_sink_convert_bin_add_identity (GstPlaySinkConvertBin * self)
{
  if (self->identity)
    return;

  self->identity = gst_element_factory_make ("identity", "identity");
  if (self->identity == NULL) {
    gst_play_sink_convert_bin_post_missing_element_message (self, "identity");
    GST_ELEMENT_WARNING (self, CORE, MISSING_PLUGIN,
        (_("Missing element '%s' - check your GStreamer installation."),
            "identity"), (self->audio ?
            "audio rendering might fail" : "video rendering might fail")

        );
  } else {
    g_object_set (self->identity, "silent", TRUE, "signal-handoffs", FALSE,
        NULL);
    gst_bin_add (GST_BIN_CAST (self), self->identity);
  }
}

static void
gst_play_sink_convert_bin_set_targets (GstPlaySinkConvertBin * self,
    gboolean passthrough)
{
  GstPad *pad;
  GstElement *head, *tail;

  GST_DEBUG_OBJECT (self, "Setting pad targets with passthrough %d",
      passthrough);
  if (self->conversion_elements == NULL || passthrough) {
    GST_DEBUG_OBJECT (self, "no conversion elements, using identity (%p) as "
        "head/tail", self->identity);
    if (!passthrough) {
      GST_WARNING_OBJECT (self,
          "Doing passthrough as no converter elements were added");
    }
    head = tail = self->identity;
  } else {
    head = GST_ELEMENT (g_list_first (self->conversion_elements)->data);
    tail = GST_ELEMENT (g_list_last (self->conversion_elements)->data);
    GST_DEBUG_OBJECT (self, "conversion elements in use, picking "
        "head:%s and tail:%s", GST_OBJECT_NAME (head), GST_OBJECT_NAME (tail));
  }

  g_return_if_fail (head != NULL);
  g_return_if_fail (tail != NULL);

  pad = gst_element_get_static_pad (head, "sink");
  GST_DEBUG_OBJECT (self, "Ghosting bin sink pad to %" GST_PTR_FORMAT, pad);
  gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->sinkpad), pad);
  gst_object_unref (pad);

  pad = gst_element_get_static_pad (tail, "src");
  GST_DEBUG_OBJECT (self, "Ghosting bin src pad to %" GST_PTR_FORMAT, pad);
  gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->srcpad), pad);
  gst_object_unref (pad);
}

static void
gst_play_sink_convert_bin_remove_element (GstElement * element,
    GstPlaySinkConvertBin * self)
{
  gst_element_set_state (element, GST_STATE_NULL);
  gst_object_unref (element);
  gst_bin_remove (GST_BIN_CAST (self), element);
}

static void
gst_play_sink_convert_bin_on_element_added (GstElement * element,
    GstPlaySinkConvertBin * self)
{
  gst_element_sync_state_with_parent (element);
}

static GstPadProbeReturn
pad_blocked_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
{
  GstPlaySinkConvertBin *self = user_data;
  GstPad *peer;
  GstCaps *caps;
  gboolean raw;

  if (GST_IS_EVENT (info->data) && !GST_EVENT_IS_SERIALIZED (info->data)) {
    GST_DEBUG_OBJECT (self, "Letting non-serialized event %s pass",
        GST_EVENT_TYPE_NAME (info->data));
    return GST_PAD_PROBE_PASS;
  }

  GST_PLAY_SINK_CONVERT_BIN_LOCK (self);
  GST_DEBUG_OBJECT (self, "Pad blocked");

  /* There must be a peer at this point */
  peer = gst_pad_get_peer (self->sinkpad);
  caps = gst_pad_get_current_caps (peer);
  if (!caps)
    caps = gst_pad_query_caps (peer, NULL);
  gst_object_unref (peer);

  raw = is_raw_caps (caps, self->audio);
  GST_DEBUG_OBJECT (self, "Caps %" GST_PTR_FORMAT " are raw: %d", caps, raw);
  gst_caps_unref (caps);

  if (raw == self->raw)
    goto unblock;
  self->raw = raw;

  gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->sinkpad), NULL);
  gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->srcpad), NULL);

  if (raw) {
    GST_DEBUG_OBJECT (self, "Switching to raw conversion pipeline");

    if (self->conversion_elements)
      g_list_foreach (self->conversion_elements,
          (GFunc) gst_play_sink_convert_bin_on_element_added, self);
  } else {

    GST_DEBUG_OBJECT (self, "Switch to passthrough pipeline");

    gst_play_sink_convert_bin_on_element_added (self->identity, self);
  }

  gst_play_sink_convert_bin_set_targets (self, !raw);

unblock:
  self->sink_proxypad_block_id = 0;
  GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self);

  return GST_PAD_PROBE_REMOVE;
}

static gboolean
gst_play_sink_convert_bin_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event)
{
  GstPlaySinkConvertBin *self = GST_PLAY_SINK_CONVERT_BIN (parent);
  gboolean ret;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CAPS:
    {
      GstCaps *caps;

      gst_event_parse_caps (event, &caps);
      gst_play_sink_convert_bin_sink_setcaps (self, caps);
      break;
    }
    default:
      break;
  }

  ret = gst_pad_event_default (pad, parent, gst_event_ref (event));

  gst_event_unref (event);

  return ret;
}

static void
block_proxypad (GstPlaySinkConvertBin * self)
{
  if (self->sink_proxypad_block_id == 0) {
    self->sink_proxypad_block_id =
        gst_pad_add_probe (self->sink_proxypad,
        GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM, pad_blocked_cb, self, NULL);
  }
}

static void
unblock_proxypad (GstPlaySinkConvertBin * self)
{
  if (self->sink_proxypad_block_id != 0) {
    gst_pad_remove_probe (self->sink_proxypad, self->sink_proxypad_block_id);
    self->sink_proxypad_block_id = 0;
  }
}

static void
gst_play_sink_convert_bin_sink_setcaps (GstPlaySinkConvertBin * self,
    GstCaps * caps)
{
  GstStructure *s;
  const gchar *name;
  gboolean reconfigure = FALSE;
  gboolean raw;

  GST_DEBUG_OBJECT (self, "Setting sink caps %" GST_PTR_FORMAT, caps);

  GST_PLAY_SINK_CONVERT_BIN_LOCK (self);
  s = gst_caps_get_structure (caps, 0);
  name = gst_structure_get_name (s);

  if (self->audio) {
    raw = g_str_equal (name, "audio/x-raw");
  } else {
    raw = g_str_equal (name, "video/x-raw");
  }

  GST_DEBUG_OBJECT (self, "raw %d, self->raw %d, blocked %d",
      raw, self->raw, gst_pad_is_blocked (self->sink_proxypad));

  if (raw) {
    if (!gst_pad_is_blocked (self->sink_proxypad)) {
      GstPad *target = gst_ghost_pad_get_target (GST_GHOST_PAD (self->sinkpad));

      if (!self->raw || (target && !gst_pad_query_accept_caps (target, caps))) {
        if (!self->raw)
          GST_DEBUG_OBJECT (self, "Changing caps from non-raw to raw");
        else
          GST_DEBUG_OBJECT (self, "Changing caps in an incompatible way");

        reconfigure = TRUE;
        block_proxypad (self);
      }

      if (target)
        gst_object_unref (target);
    }
  } else {
    if (self->raw && !gst_pad_is_blocked (self->sink_proxypad)) {
      GST_DEBUG_OBJECT (self, "Changing caps from raw to non-raw");
      reconfigure = TRUE;
      block_proxypad (self);
    }
  }

  /* Otherwise the setcaps below fails */
  if (reconfigure) {
    gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->sinkpad), NULL);
    gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->srcpad), NULL);
  }

  GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self);
}

#define GST_PLAY_SINK_CONVERT_BIN_FILTER_CAPS(filter,caps) G_STMT_START {     \
  if ((filter)) {                                                             \
    GstCaps *intersection =                                                   \
        gst_caps_intersect_full ((filter), (caps), GST_CAPS_INTERSECT_FIRST); \
    gst_caps_unref ((caps));                                                  \
    (caps) = intersection;                                                    \
  }                                                                           \
} G_STMT_END

static gboolean
gst_play_sink_convert_bin_acceptcaps (GstPad * pad, GstCaps * caps)
{
  GstPlaySinkConvertBin *self =
      GST_PLAY_SINK_CONVERT_BIN (gst_pad_get_parent (pad));
  gboolean ret;
  GstPad *otherpad;

  GST_PLAY_SINK_CONVERT_BIN_LOCK (self);
  if (pad == self->srcpad) {
    otherpad = self->sinkpad;
  } else if (pad == self->sinkpad) {
    otherpad = self->srcpad;
  } else {
    GST_ERROR_OBJECT (pad, "Not one of our pads");
    otherpad = NULL;
  }

  if (otherpad) {
    ret = gst_pad_peer_query_accept_caps (otherpad, caps);
    if (!ret && self->converter_caps) {
      /* maybe we can convert */
      ret = gst_caps_can_intersect (caps, self->converter_caps);
    }
  } else {
    ret = TRUE;
  }
  GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self);

  gst_object_unref (self);

  GST_DEBUG_OBJECT (pad, "Accept caps: '%" GST_PTR_FORMAT "' %d", caps, ret);

  return ret;
}

static GstCaps *
gst_play_sink_convert_bin_getcaps (GstPad * pad, GstCaps * filter)
{
  GstPlaySinkConvertBin *self =
      GST_PLAY_SINK_CONVERT_BIN (gst_pad_get_parent (pad));
  GstCaps *ret;
  GstPad *otherpad, *peer;

  GST_PLAY_SINK_CONVERT_BIN_LOCK (self);
  if (pad == self->srcpad) {
    otherpad = self->sinkpad;
  } else if (pad == self->sinkpad) {
    otherpad = self->srcpad;
  } else {
    GST_ERROR_OBJECT (pad, "Not one of our pads");
    otherpad = NULL;
  }

  if (otherpad) {
    peer = gst_pad_get_peer (otherpad);
    if (peer) {
      GstCaps *peer_caps;
      GstCaps *downstream_filter = NULL;

      /* Add all the caps that we can convert to to the filter caps,
       * otherwise downstream might just return EMPTY caps because
       * it doesn't handle the filter caps but we could still convert
       * to these caps */
      if (filter) {
        guint i, n;

        downstream_filter = gst_caps_new_empty ();

        /* Intersect raw video caps in the filter caps with the converter
         * caps. This makes sure that we don't accept raw video that we
         * can't handle, e.g. because of caps features */
        n = gst_caps_get_size (filter);
        for (i = 0; i < n; i++) {
          GstStructure *s;
          GstCaps *tmp, *tmp2;

          s = gst_structure_copy (gst_caps_get_structure (filter, i));
          if (gst_structure_has_name (s,
                  self->audio ? "audio/x-raw" : "video/x-raw")) {
            tmp = gst_caps_new_full (s, NULL);
            tmp2 = gst_caps_intersect (tmp, self->converter_caps);
            gst_caps_append (downstream_filter, tmp2);
            gst_caps_unref (tmp);
          } else {
            gst_caps_append_structure (downstream_filter, s);
          }
        }
        downstream_filter =
            gst_caps_merge (downstream_filter,
            gst_caps_ref (self->converter_caps));
      }

      peer_caps = gst_pad_query_caps (peer, downstream_filter);
      if (downstream_filter)
        gst_caps_unref (downstream_filter);
      gst_object_unref (peer);
      if (self->converter_caps && is_raw_caps (peer_caps, self->audio)) {
        GstCaps *converter_caps = gst_caps_ref (self->converter_caps);
        GstCapsFeatures *cf;
        GstStructure *s;
        guint i, n;

        ret = gst_caps_make_writable (peer_caps);

        /* Filter out ANY capsfeatures from the converter caps. We can't
         * convert to ANY capsfeatures, they are only there so that we
         * can passthrough whatever downstream can support... but we
         * definitely don't want to return them here
         */
        n = gst_caps_get_size (converter_caps);
        for (i = 0; i < n; i++) {
          s = gst_caps_get_structure (converter_caps, i);
          cf = gst_caps_get_features (converter_caps, i);

          if (cf && gst_caps_features_is_any (cf))
            continue;
          ret =
              gst_caps_merge_structure_full (ret, gst_structure_copy (s),
              (cf ? gst_caps_features_copy (cf) : NULL));
        }
        gst_caps_unref (converter_caps);
      } else {
        ret = peer_caps;
      }
    } else {
      ret = gst_caps_ref (self->converter_caps);
    }
    GST_PLAY_SINK_CONVERT_BIN_FILTER_CAPS (filter, ret);

  } else {
    ret = filter ? gst_caps_ref (filter) : gst_caps_new_any ();
  }
  GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self);

  gst_object_unref (self);

  GST_DEBUG_OBJECT (pad, "Returning caps %" GST_PTR_FORMAT, ret);

  return ret;
}

static gboolean
gst_play_sink_convert_bin_query (GstPad * pad, GstObject * parent,
    GstQuery * query)
{
  gboolean res = FALSE;

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_CAPS:
    {
      GstCaps *filter, *caps;

      gst_query_parse_caps (query, &filter);
      caps = gst_play_sink_convert_bin_getcaps (pad, filter);
      gst_query_set_caps_result (query, caps);
      gst_caps_unref (caps);
      res = TRUE;
      break;
    }
    case GST_QUERY_ACCEPT_CAPS:
    {
      gboolean ret;
      GstCaps *caps;

      gst_query_parse_accept_caps (query, &caps);
      ret = gst_play_sink_convert_bin_acceptcaps (pad, caps);
      gst_query_set_accept_caps_result (query, ret);
      res = TRUE;
      break;
    }
    default:
      res = gst_pad_query_default (pad, parent, query);
      break;
  }
  return res;
}

void
gst_play_sink_convert_bin_remove_elements (GstPlaySinkConvertBin * self)
{
  if (self->conversion_elements) {
    g_list_foreach (self->conversion_elements,
        (GFunc) gst_play_sink_convert_bin_remove_element, self);
    g_list_free (self->conversion_elements);
    self->conversion_elements = NULL;
  }
  if (self->converter_caps) {
    gst_caps_unref (self->converter_caps);
    self->converter_caps = NULL;
  }
}

static void
gst_play_sink_convert_bin_dispose (GObject * object)
{
  GstPlaySinkConvertBin *self = GST_PLAY_SINK_CONVERT_BIN_CAST (object);

  gst_play_sink_convert_bin_remove_elements (self);

  G_OBJECT_CLASS (parent_class)->dispose (object);
}

static void
gst_play_sink_convert_bin_finalize (GObject * object)
{
  GstPlaySinkConvertBin *self = GST_PLAY_SINK_CONVERT_BIN_CAST (object);

  gst_object_unref (self->sink_proxypad);
  g_mutex_clear (&self->lock);

  G_OBJECT_CLASS (parent_class)->finalize (object);
}

void
gst_play_sink_convert_bin_cache_converter_caps (GstPlaySinkConvertBin * self)
{
  GstElement *head;
  GstPad *pad;

  if (self->converter_caps) {
    gst_caps_unref (self->converter_caps);
    self->converter_caps = NULL;
  }

  if (!self->conversion_elements) {
    GST_INFO_OBJECT (self, "No conversion elements");
    return;
  }

  head = GST_ELEMENT (g_list_first (self->conversion_elements)->data);
  pad = gst_element_get_static_pad (head, "sink");
  if (!pad) {
    GST_WARNING_OBJECT (self, "No sink pad found");
    return;
  }

  self->converter_caps = gst_pad_query_caps (pad, NULL);
  GST_INFO_OBJECT (self, "Converter caps: %" GST_PTR_FORMAT,
      self->converter_caps);

  gst_object_unref (pad);
}

static GstStateChangeReturn
gst_play_sink_convert_bin_change_state (GstElement * element,
    GstStateChange transition)
{
  GstStateChangeReturn ret;
  GstPlaySinkConvertBin *self = GST_PLAY_SINK_CONVERT_BIN_CAST (element);

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      GST_PLAY_SINK_CONVERT_BIN_LOCK (self);
      unblock_proxypad (self);
      GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self);
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      GST_PLAY_SINK_CONVERT_BIN_LOCK (self);
      gst_play_sink_convert_bin_set_targets (self, TRUE);
      self->raw = FALSE;
      GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self);
      break;
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
  if (ret == GST_STATE_CHANGE_FAILURE)
    return ret;

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      GST_PLAY_SINK_CONVERT_BIN_LOCK (self);
      gst_play_sink_convert_bin_set_targets (self, TRUE);
      self->raw = FALSE;
      GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self);
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      GST_PLAY_SINK_CONVERT_BIN_LOCK (self);
      unblock_proxypad (self);
      GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self);
      break;
    default:
      break;
  }

  return ret;
}

static void
gst_play_sink_convert_bin_class_init (GstPlaySinkConvertBinClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;

  GST_DEBUG_CATEGORY_INIT (gst_play_sink_convert_bin_debug,
      "playsinkconvertbin", 0, "play bin");

  gobject_class = (GObjectClass *) klass;
  gstelement_class = (GstElementClass *) klass;

  gobject_class->dispose = gst_play_sink_convert_bin_dispose;
  gobject_class->finalize = gst_play_sink_convert_bin_finalize;

  gst_element_class_add_static_pad_template (gstelement_class, &srctemplate);
  gst_element_class_add_static_pad_template (gstelement_class, &sinktemplate);
  gst_element_class_set_static_metadata (gstelement_class,
      "Player Sink Converter Bin", "Bin/Converter",
      "Convenience bin for audio/video conversion",
      "Sebastian Dröge <sebastian.droege@collabora.co.uk>");

  gstelement_class->change_state =
      GST_DEBUG_FUNCPTR (gst_play_sink_convert_bin_change_state);
}

static void
gst_play_sink_convert_bin_init (GstPlaySinkConvertBin * self)
{
  GstPadTemplate *templ;

  g_mutex_init (&self->lock);

  templ = gst_static_pad_template_get (&sinktemplate);
  self->sinkpad = gst_ghost_pad_new_no_target_from_template ("sink", templ);
  gst_pad_set_event_function (self->sinkpad,
      GST_DEBUG_FUNCPTR (gst_play_sink_convert_bin_sink_event));
  gst_pad_set_query_function (self->sinkpad,
      GST_DEBUG_FUNCPTR (gst_play_sink_convert_bin_query));

  self->sink_proxypad =
      GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD (self->sinkpad)));

  gst_element_add_pad (GST_ELEMENT_CAST (self), self->sinkpad);
  gst_object_unref (templ);

  templ = gst_static_pad_template_get (&srctemplate);
  self->srcpad = gst_ghost_pad_new_no_target_from_template ("src", templ);
  gst_pad_set_query_function (self->srcpad,
      GST_DEBUG_FUNCPTR (gst_play_sink_convert_bin_query));
  gst_element_add_pad (GST_ELEMENT_CAST (self), self->srcpad);
  gst_object_unref (templ);

  gst_play_sink_convert_bin_add_identity (self);
}
