/* GStreamer video frame cropping to aspect-ratio
 * Copyright (C) 2009 Thijs Vermeir <thijsvermeir@gmail.com>
 *
 * 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.
 */

/**
 * SECTION:element-aspectratiocrop
 * @see_also: #GstVideoCrop
 *
 * This element crops video frames to a specified #GstAspectRatioCrop:aspect-ratio.
 *
 * If the aspect-ratio is already correct, the element will operate
 * in pass-through mode.
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch-1.0 -v videotestsrc ! video/x-raw,height=640,width=480 ! aspectratiocrop aspect-ratio=16/9 ! ximagesink
 * ]| This pipeline generates a videostream in 4/3 and crops it to 16/9.
 * </refsect2>
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <gst/gst.h>
#include <gst/video/video.h>

#include "gstaspectratiocrop.h"

#include "gst/glib-compat-private.h"

GST_DEBUG_CATEGORY_STATIC (aspect_ratio_crop_debug);
#define GST_CAT_DEFAULT aspect_ratio_crop_debug

enum
{
  ARG_0,
  ARG_ASPECT_RATIO_CROP,
};

/* we support the same caps as videocrop (sync changes) */
#define ASPECT_RATIO_CROP_CAPS                        \
  GST_VIDEO_CAPS_MAKE ("{ RGBx, xRGB, BGRx, xBGR, "    \
      "RGBA, ARGB, BGRA, ABGR, RGB, BGR, AYUV, YUY2, " \
      "YVYU, UYVY, I420, YV12, RGB16, RGB15, GRAY8, "  \
      "NV12, NV21, GRAY16_LE, GRAY16_BE }")

static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (ASPECT_RATIO_CROP_CAPS)
    );

static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (ASPECT_RATIO_CROP_CAPS)
    );

#define gst_aspect_ratio_crop_parent_class parent_class
G_DEFINE_TYPE (GstAspectRatioCrop, gst_aspect_ratio_crop, GST_TYPE_BIN);

static void gst_aspect_ratio_crop_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_aspect_ratio_crop_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static void gst_aspect_ratio_crop_set_cropping (GstAspectRatioCrop *
    aspect_ratio_crop, gint top, gint right, gint bottom, gint left);
static GstCaps *gst_aspect_ratio_crop_get_caps (GstPad * pad, GstCaps * filter);
static gboolean gst_aspect_ratio_crop_src_query (GstPad * pad,
    GstObject * parent, GstQuery * query);
static gboolean gst_aspect_ratio_crop_set_caps (GstAspectRatioCrop *
    aspect_ratio_crop, GstCaps * caps);
static gboolean gst_aspect_ratio_crop_sink_event (GstPad * pad,
    GstObject * parent, GstEvent * evt);
static void gst_aspect_ratio_crop_finalize (GObject * object);
static void gst_aspect_ratio_transform_structure (GstAspectRatioCrop *
    aspect_ratio_crop, GstStructure * structure, GstStructure ** new_structure,
    gboolean set_videocrop);

static void
gst_aspect_ratio_crop_set_cropping (GstAspectRatioCrop * aspect_ratio_crop,
    gint top, gint right, gint bottom, gint left)
{
  GValue value = { 0 };
  if (G_UNLIKELY (!aspect_ratio_crop->videocrop)) {
    GST_WARNING_OBJECT (aspect_ratio_crop,
        "Can't set the settings if there is no cropping element");
    return;
  }

  g_value_init (&value, G_TYPE_INT);
  g_value_set_int (&value, top);
  GST_DEBUG_OBJECT (aspect_ratio_crop, "set top cropping to: %d", top);
  g_object_set_property (G_OBJECT (aspect_ratio_crop->videocrop), "top",
      &value);
  g_value_set_int (&value, right);
  GST_DEBUG_OBJECT (aspect_ratio_crop, "set right cropping to: %d", right);
  g_object_set_property (G_OBJECT (aspect_ratio_crop->videocrop), "right",
      &value);
  g_value_set_int (&value, bottom);
  GST_DEBUG_OBJECT (aspect_ratio_crop, "set bottom cropping to: %d", bottom);
  g_object_set_property (G_OBJECT (aspect_ratio_crop->videocrop), "bottom",
      &value);
  g_value_set_int (&value, left);
  GST_DEBUG_OBJECT (aspect_ratio_crop, "set left cropping to: %d", left);
  g_object_set_property (G_OBJECT (aspect_ratio_crop->videocrop), "left",
      &value);

  g_value_unset (&value);
}

static gboolean
gst_aspect_ratio_crop_set_caps (GstAspectRatioCrop * aspect_ratio_crop,
    GstCaps * caps)
{
  GstPad *peer_pad;
  GstStructure *structure;
  gboolean ret;

  g_mutex_lock (&aspect_ratio_crop->crop_lock);

  structure = gst_caps_get_structure (caps, 0);
  gst_aspect_ratio_transform_structure (aspect_ratio_crop, structure, NULL,
      TRUE);
  peer_pad =
      gst_element_get_static_pad (GST_ELEMENT (aspect_ratio_crop->videocrop),
      "sink");
  ret = gst_pad_set_caps (peer_pad, caps);
  gst_object_unref (peer_pad);
  g_mutex_unlock (&aspect_ratio_crop->crop_lock);
  return ret;
}

static gboolean
gst_aspect_ratio_crop_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * evt)
{
  gboolean ret;
  GstAspectRatioCrop *aspect_ratio_crop = GST_ASPECT_RATIO_CROP (parent);

  ret =
      aspect_ratio_crop->sinkpad_old_eventfunc (pad, parent,
      gst_event_ref (evt));

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

      gst_event_parse_caps (evt, &caps);
      ret = gst_aspect_ratio_crop_set_caps (aspect_ratio_crop, caps);
      break;
    }
    default:
      break;
  }
  gst_event_unref (evt);

  return ret;
}

static void
gst_aspect_ratio_crop_class_init (GstAspectRatioCropClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *element_class;

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

  gobject_class->set_property = gst_aspect_ratio_crop_set_property;
  gobject_class->get_property = gst_aspect_ratio_crop_get_property;
  gobject_class->finalize = gst_aspect_ratio_crop_finalize;

  g_object_class_install_property (gobject_class, ARG_ASPECT_RATIO_CROP,
      gst_param_spec_fraction ("aspect-ratio", "aspect-ratio",
          "Target aspect-ratio of video", 0, 1, G_MAXINT, 1, 0, 1,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  gst_element_class_set_static_metadata (element_class, "aspectratiocrop",
      "Filter/Effect/Video",
      "Crops video into a user-defined aspect-ratio",
      "Thijs Vermeir <thijsvermeir@gmail.com>");

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&sink_template));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&src_template));
}

static void
gst_aspect_ratio_crop_finalize (GObject * object)
{
  GstAspectRatioCrop *aspect_ratio_crop;

  aspect_ratio_crop = GST_ASPECT_RATIO_CROP (object);

  g_mutex_clear (&aspect_ratio_crop->crop_lock);

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

static void
gst_aspect_ratio_crop_init (GstAspectRatioCrop * aspect_ratio_crop)
{
  GstPad *link_pad;
  GstPad *src_pad;

  GST_DEBUG_CATEGORY_INIT (aspect_ratio_crop_debug, "aspectratiocrop", 0,
      "aspectratiocrop");

  aspect_ratio_crop->ar_num = 0;
  aspect_ratio_crop->ar_denom = 1;

  g_mutex_init (&aspect_ratio_crop->crop_lock);

  /* add the transform element */
  aspect_ratio_crop->videocrop = gst_element_factory_make ("videocrop", NULL);
  gst_bin_add (GST_BIN (aspect_ratio_crop), aspect_ratio_crop->videocrop);

  /* create ghost pad src */
  link_pad =
      gst_element_get_static_pad (GST_ELEMENT (aspect_ratio_crop->videocrop),
      "src");
  src_pad = gst_ghost_pad_new ("src", link_pad);
  gst_pad_set_query_function (src_pad,
      GST_DEBUG_FUNCPTR (gst_aspect_ratio_crop_src_query));
  gst_element_add_pad (GST_ELEMENT (aspect_ratio_crop), src_pad);
  gst_object_unref (link_pad);
  /* create ghost pad sink */
  link_pad =
      gst_element_get_static_pad (GST_ELEMENT (aspect_ratio_crop->videocrop),
      "sink");
  aspect_ratio_crop->sink = gst_ghost_pad_new ("sink", link_pad);
  gst_element_add_pad (GST_ELEMENT (aspect_ratio_crop),
      aspect_ratio_crop->sink);
  gst_object_unref (link_pad);

  aspect_ratio_crop->sinkpad_old_eventfunc =
      GST_PAD_EVENTFUNC (aspect_ratio_crop->sink);
  gst_pad_set_event_function (aspect_ratio_crop->sink,
      GST_DEBUG_FUNCPTR (gst_aspect_ratio_crop_sink_event));
}

static void
gst_aspect_ratio_transform_structure (GstAspectRatioCrop * aspect_ratio_crop,
    GstStructure * structure, GstStructure ** new_structure,
    gboolean set_videocrop)
{
  gdouble incoming_ar;
  gdouble requested_ar;
  gint width, height;
  gint cropvalue;
  gint par_d, par_n;

  /* Check if we need to change the aspect ratio */
  if (aspect_ratio_crop->ar_num < 1) {
    GST_DEBUG_OBJECT (aspect_ratio_crop, "No cropping requested");
    goto beach;
  }

  /* get the information from the caps */
  if (!gst_structure_get_int (structure, "width", &width) ||
      !gst_structure_get_int (structure, "height", &height))
    goto beach;

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

  incoming_ar = ((gdouble) (width * par_n)) / (height * par_d);
  GST_LOG_OBJECT (aspect_ratio_crop,
      "incoming caps width(%d), height(%d), par (%d/%d) : ar = %f", width,
      height, par_n, par_d, incoming_ar);

  requested_ar =
      (gdouble) aspect_ratio_crop->ar_num / aspect_ratio_crop->ar_denom;

  /* check if the original aspect-ratio is the aspect-ratio that we want */
  if (requested_ar == incoming_ar) {
    GST_DEBUG_OBJECT (aspect_ratio_crop,
        "Input video already has the correct aspect ratio (%.3f == %.3f)",
        incoming_ar, requested_ar);
    goto beach;
  } else if (requested_ar > incoming_ar) {
    /* fix aspect ratio with cropping on top and bottom */
    cropvalue =
        ((((double) aspect_ratio_crop->ar_denom /
                (double) (aspect_ratio_crop->ar_num)) * ((double) par_n /
                (double) par_d) * width) - height) / 2;
    if (cropvalue < 0) {
      cropvalue *= -1;
    }
    if (cropvalue >= (height / 2))
      goto crop_failed;
    if (set_videocrop) {
      gst_aspect_ratio_crop_set_cropping (aspect_ratio_crop, cropvalue, 0,
          cropvalue, 0);
    }
    if (new_structure) {
      *new_structure = gst_structure_copy (structure);
      gst_structure_set (*new_structure,
          "height", G_TYPE_INT, (int) (height - (cropvalue * 2)), NULL);
    }
  } else {
    /* fix aspect ratio with cropping on left and right */
    cropvalue =
        ((((double) aspect_ratio_crop->ar_num /
                (double) (aspect_ratio_crop->ar_denom)) * ((double) par_d /
                (double) par_n) * height) - width) / 2;
    if (cropvalue < 0) {
      cropvalue *= -1;
    }
    if (cropvalue >= (width / 2))
      goto crop_failed;
    if (set_videocrop) {
      gst_aspect_ratio_crop_set_cropping (aspect_ratio_crop, 0, cropvalue,
          0, cropvalue);
    }
    if (new_structure) {
      *new_structure = gst_structure_copy (structure);
      gst_structure_set (*new_structure,
          "width", G_TYPE_INT, (int) (width - (cropvalue * 2)), NULL);
    }
  }

  return;

crop_failed:
  GST_WARNING_OBJECT (aspect_ratio_crop,
      "can't crop to aspect ratio requested");
  goto beach;
beach:
  if (set_videocrop) {
    gst_aspect_ratio_crop_set_cropping (aspect_ratio_crop, 0, 0, 0, 0);
  }

  if (new_structure) {
    *new_structure = gst_structure_copy (structure);
  }
}

static GstCaps *
gst_aspect_ratio_crop_transform_caps (GstAspectRatioCrop * aspect_ratio_crop,
    GstCaps * caps)
{
  GstCaps *transform;
  gint size, i;

  transform = gst_caps_new_empty ();

  size = gst_caps_get_size (caps);

  for (i = 0; i < size; i++) {
    GstStructure *s;
    GstStructure *trans_s;

    s = gst_caps_get_structure (caps, i);

    gst_aspect_ratio_transform_structure (aspect_ratio_crop, s, &trans_s,
        FALSE);
    gst_caps_append_structure (transform, trans_s);
  }

  return transform;
}

static GstCaps *
gst_aspect_ratio_crop_get_caps (GstPad * pad, GstCaps * filter)
{
  GstPad *peer;
  GstAspectRatioCrop *aspect_ratio_crop;
  GstCaps *return_caps;

  aspect_ratio_crop = GST_ASPECT_RATIO_CROP (gst_pad_get_parent (pad));

  g_mutex_lock (&aspect_ratio_crop->crop_lock);

  peer = gst_pad_get_peer (aspect_ratio_crop->sink);
  if (peer == NULL) {
    return_caps = gst_static_pad_template_get_caps (&src_template);
  } else {
    GstCaps *peer_caps;

    peer_caps = gst_pad_query_caps (peer, filter);
    return_caps =
        gst_aspect_ratio_crop_transform_caps (aspect_ratio_crop, peer_caps);
    gst_caps_unref (peer_caps);
    gst_object_unref (peer);
  }

  g_mutex_unlock (&aspect_ratio_crop->crop_lock);
  gst_object_unref (aspect_ratio_crop);

  if (return_caps && filter) {
    GstCaps *tmp =
        gst_caps_intersect_full (filter, return_caps, GST_CAPS_INTERSECT_FIRST);
    gst_caps_replace (&return_caps, tmp);
    gst_caps_unref (tmp);
  }

  return return_caps;
}

static gboolean
gst_aspect_ratio_crop_src_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_aspect_ratio_crop_get_caps (pad, filter);
      gst_query_set_caps_result (query, caps);
      gst_caps_unref (caps);
      res = TRUE;
      break;
    }
    default:
      res = gst_pad_query_default (pad, parent, query);
      break;
  }
  return res;
}

static void
gst_aspect_ratio_crop_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstAspectRatioCrop *aspect_ratio_crop;
  gboolean recheck = FALSE;

  aspect_ratio_crop = GST_ASPECT_RATIO_CROP (object);

  GST_OBJECT_LOCK (aspect_ratio_crop);
  switch (prop_id) {
    case ARG_ASPECT_RATIO_CROP:
      if (GST_VALUE_HOLDS_FRACTION (value)) {
        aspect_ratio_crop->ar_num = gst_value_get_fraction_numerator (value);
        aspect_ratio_crop->ar_denom =
            gst_value_get_fraction_denominator (value);
        recheck = gst_pad_has_current_caps (aspect_ratio_crop->sink);
      }
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
  GST_OBJECT_UNLOCK (aspect_ratio_crop);

  if (recheck) {
    GstCaps *caps = gst_pad_get_current_caps (aspect_ratio_crop->sink);
    gst_aspect_ratio_crop_set_caps (aspect_ratio_crop, caps);
    gst_caps_unref (caps);
  }
}

static void
gst_aspect_ratio_crop_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstAspectRatioCrop *aspect_ratio_crop;

  aspect_ratio_crop = GST_ASPECT_RATIO_CROP (object);

  GST_OBJECT_LOCK (aspect_ratio_crop);
  switch (prop_id) {
    case ARG_ASPECT_RATIO_CROP:
      gst_value_set_fraction (value, aspect_ratio_crop->ar_num,
          aspect_ratio_crop->ar_denom);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
  GST_OBJECT_UNLOCK (aspect_ratio_crop);
}
