/*
 * Copyright (C) 2008 Jan Schmidt <thaytan@noraisin.net>
 */

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <gst/gst.h>
#include <gst/glib-compat-private.h>
#include <gst/video/video.h>
#include <string.h>

#include "rsnparsetter.h"

GST_DEBUG_CATEGORY_STATIC (rsn_parsetter_debug);
#define GST_CAT_DEFAULT rsn_parsetter_debug

static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL))
    );

static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL))
    );

#define rsn_parsetter_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (RsnParSetter, rsn_parsetter, GST_TYPE_ELEMENT,
    GST_DEBUG_CATEGORY_INIT (rsn_parsetter_debug, "rsnparsetter", 0,
        "Resin DVD aspect ratio adjuster"));

static void rsn_parsetter_finalize (GObject * object);
static GstFlowReturn rsn_parsetter_chain (GstPad * pad,
    RsnParSetter * parset, GstBuffer * buf);
static gboolean rsn_parsetter_sink_event (GstPad * pad,
    RsnParSetter * parset, GstEvent * event);

static gboolean rsn_parsetter_src_query (GstPad * pad, RsnParSetter * parset,
    GstQuery * query);
static GstCaps *rsn_parsetter_convert_caps (RsnParSetter * parset,
    GstCaps * caps, gboolean widescreen);
static gboolean rsn_parsetter_check_caps (RsnParSetter * parset,
    GstCaps * caps);
static void rsn_parsetter_update_caps (RsnParSetter * parset, GstCaps * caps);

static void
rsn_parsetter_class_init (RsnParSetterClass * klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);

  gobject_class->finalize = rsn_parsetter_finalize;

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&src_factory));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&sink_factory));

  gst_element_class_set_static_metadata (element_class,
      "Resin Aspect Ratio Setter", "Filter/Video",
      "Overrides caps on video buffers to force a particular display ratio",
      "Jan Schmidt <thaytan@noraisin.net>");
}

static void
rsn_parsetter_init (RsnParSetter * parset)
{
  parset->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink");
  gst_pad_set_chain_function (parset->sinkpad,
      (GstPadChainFunction) GST_DEBUG_FUNCPTR (rsn_parsetter_chain));
  gst_pad_set_event_function (parset->sinkpad,
      (GstPadEventFunction) GST_DEBUG_FUNCPTR (rsn_parsetter_sink_event));
  GST_PAD_SET_PROXY_CAPS (parset->sinkpad);
  GST_PAD_SET_PROXY_ALLOCATION (parset->sinkpad);
  gst_element_add_pad (GST_ELEMENT (parset), parset->sinkpad);

  parset->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
  gst_pad_set_query_function (parset->srcpad,
      (GstPadQueryFunction) GST_DEBUG_FUNCPTR (rsn_parsetter_src_query));
  GST_PAD_SET_PROXY_CAPS (parset->srcpad);
  gst_element_add_pad (GST_ELEMENT (parset), parset->srcpad);
}

static void
rsn_parsetter_finalize (GObject * object)
{
  RsnParSetter *parset = RSN_PARSETTER (object);

  gst_caps_replace (&parset->outcaps, NULL);
  gst_caps_replace (&parset->in_caps_last, NULL);
  gst_caps_replace (&parset->in_caps_converted, NULL);

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

static GstFlowReturn
rsn_parsetter_chain (GstPad * pad, RsnParSetter * parset, GstBuffer * buf)
{
  return gst_pad_push (parset->srcpad, buf);
}

static gboolean
rsn_parsetter_sink_event (GstPad * pad, RsnParSetter * parset, GstEvent * event)
{
  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CUSTOM_DOWNSTREAM:{
      const GstStructure *structure = gst_event_get_structure (event);

      if (structure != NULL &&
          gst_structure_has_name (structure, "application/x-gst-dvd")) {
        const char *type = gst_structure_get_string (structure, "event");
        GstEvent *caps_event = NULL;

        if (type == NULL)
          goto out;

        if (strcmp (type, "dvd-video-format") == 0) {
          gboolean is_widescreen;

          gst_structure_get_boolean (structure, "video-widescreen",
              &is_widescreen);

          GST_DEBUG_OBJECT (parset, "Video is %s",
              parset->is_widescreen ? "16:9" : "4:3");

          if (parset->in_caps_last && parset->is_widescreen != is_widescreen) {
            /* Force caps check */
            gst_caps_replace (&parset->in_caps_converted, NULL);
            rsn_parsetter_update_caps (parset, parset->in_caps_last);
            if (parset->override_outcaps)
              caps_event = gst_event_new_caps (parset->outcaps);
          }
          parset->is_widescreen = is_widescreen;

          /* FIXME: Added for testing: */
          // parset->is_widescreen = FALSE;

          if (caps_event)
            gst_pad_push_event (parset->srcpad, caps_event);
        }
      }
      break;
    }
    case GST_EVENT_CAPS:
    {
      GstCaps *caps = NULL;
      gst_event_parse_caps (event, &caps);
      rsn_parsetter_update_caps (parset, caps);
      if (parset->override_outcaps) {
        gst_event_unref (event);
        GST_DEBUG_OBJECT (parset,
            "Handling caps event. Overriding upstream caps"
            " with %" GST_PTR_FORMAT, parset->outcaps);
        event = gst_event_new_caps (parset->outcaps);
      } else {
        GST_DEBUG_OBJECT (parset,
            "Handling caps event. Upstream caps %" GST_PTR_FORMAT
            " acceptable", caps);
      }
      break;
    }
    default:
      break;
  }

out:
  return gst_pad_event_default (pad, (GstObject *) (parset), event);
}

static gboolean
rsn_parsetter_src_query (GstPad * pad, RsnParSetter * parset, GstQuery * query)
{
  GstCaps *caps = NULL;

  if (!gst_pad_peer_query (parset->sinkpad, query))
    return FALSE;

  if (GST_QUERY_TYPE (query) != GST_QUERY_CAPS)
    return TRUE;

  gst_query_parse_caps_result (query, &caps);

  GST_DEBUG_OBJECT (parset, "Handling caps query. Upstream caps %"
      GST_PTR_FORMAT, caps);

  if (caps == NULL) {
    GstCaps *templ_caps = gst_pad_get_pad_template_caps (pad);
    gst_query_set_caps_result (query, templ_caps);
    gst_caps_unref (templ_caps);
  } else {
    caps = rsn_parsetter_convert_caps (parset, caps, parset->is_widescreen);
    gst_query_set_caps_result (query, caps);
    gst_caps_unref (caps);
  }

  return TRUE;
}

/* Check if the DAR of the passed matches the required DAR */
static gboolean
rsn_parsetter_check_caps (RsnParSetter * parset, GstCaps * caps)
{
  GstStructure *s;
  gint width, height;
  gint par_n, par_d;
  guint dar_n, dar_d;
  gboolean ret = FALSE;

  if (parset->in_caps_last &&
      (caps == parset->in_caps_last ||
          gst_caps_is_equal (caps, parset->in_caps_last))) {
    ret = parset->in_caps_was_ok;
    goto out;
  }

  /* Calculate the DAR from the incoming caps, and return TRUE if it matches
   * the required DAR, FALSE if not */
  s = gst_caps_get_structure (caps, 0);
  if (s == NULL)
    goto out;

  if (!gst_structure_get_int (s, "width", &width) ||
      !gst_structure_get_int (s, "height", &height))
    goto out;

  if (!gst_structure_get_fraction (s, "pixel-aspect-ratio", &par_n, &par_d))
    par_n = par_d = 1;

  if (!gst_video_calculate_display_ratio (&dar_n, &dar_d, width, height,
          par_n, par_d, 1, 1))
    goto out;

  GST_DEBUG_OBJECT (parset,
      "Incoming video caps now: w %d h %d PAR %d/%d = DAR %d/%d",
      width, height, par_n, par_d, dar_n, dar_d);

  if (parset->is_widescreen) {
    if (dar_n == 16 && dar_d == 9)
      ret = TRUE;
  } else {
    if (dar_n == 4 && dar_d == 3)
      ret = TRUE;
  }

  gst_caps_replace (&parset->in_caps_last, caps);
  gst_caps_replace (&parset->in_caps_converted, NULL);
  parset->in_caps_was_ok = ret;

out:
  return ret;
}

static GstCaps *
rsn_parsetter_convert_caps (RsnParSetter * parset, GstCaps * caps,
    gboolean widescreen)
{
  /* Duplicate the given caps, with a PAR that provides the desired DAR */
  GstCaps *outcaps;
  GstStructure *s;
  gint width, height;
  gint par_n, par_d;
  guint dar_n, dar_d;
  GValue par = { 0, };

  if (caps == parset->in_caps_last && parset->in_caps_converted) {
    outcaps = gst_caps_ref (parset->in_caps_converted);
    goto out;
  }

  outcaps = gst_caps_copy (caps);

  /* Calculate the DAR from the incoming caps, and return TRUE if it matches
   * the required DAR, FALSE if not */
  s = gst_caps_get_structure (outcaps, 0);
  if (s == NULL)
    goto out;

  if (!gst_structure_get_int (s, "width", &width) ||
      !gst_structure_get_int (s, "height", &height))
    goto out;

  if (widescreen) {
    dar_n = 16;
    dar_d = 9;
  } else {
    dar_n = 4;
    dar_d = 3;
  }

  par_n = dar_n * height;
  par_d = dar_d * width;

  g_value_init (&par, GST_TYPE_FRACTION);
  gst_value_set_fraction (&par, par_n, par_d);
  gst_structure_set_value (s, "pixel-aspect-ratio", &par);
  g_value_unset (&par);

  gst_caps_replace (&parset->in_caps_converted, outcaps);
out:
  return outcaps;
}

static void
rsn_parsetter_update_caps (RsnParSetter * parset, GstCaps * caps)
{
  /* Check the new incoming caps against our current DAR, and mark
   * whether the caps need adjusting */
  if (rsn_parsetter_check_caps (parset, caps)) {
    parset->override_outcaps = FALSE;
    gst_caps_replace (&parset->outcaps, caps);
  } else {
    GstCaps *override_caps = rsn_parsetter_convert_caps (parset, caps,
        parset->is_widescreen);
    if (parset->outcaps)
      gst_caps_unref (parset->outcaps);
    parset->outcaps = override_caps;

    parset->override_outcaps = TRUE;
  }

  GST_DEBUG_OBJECT (parset, "caps changed: need_override now = %d",
      parset->override_outcaps);
}
