/* GStreamer GdkPixbuf sink
 * Copyright (C) 2006-2008 Tim-Philipp Müller <tim centricular net>
 *
 * 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 free software; you can redistribute it and/or
 * 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-gdkpixbufsink
 * @Since: 0.10.8
 *
 * This sink element takes RGB or RGBA images as input and wraps them into
 * #GdkPixbuf objects, for easy saving to file via the
 * GdkPixbuf library API or displaying in Gtk+ applications (e.g. using
 * the #GtkImage widget).
 *
 * There are two ways to use this element and obtain the #GdkPixbuf objects
 * created:
 * <itemizedlist>
 * <listitem>
 * Watching for element messages named <classname>&quot;preroll-pixbuf&quot;
 * </classname> or <classname>&quot;pixbuf&quot;</classname> on the bus, which
 * will be posted whenever an image would usually be rendered. See below for
 * more details on these messages and how to extract the pixbuf object
 * contained in them.
 * </listitem>
 * <listitem>
 * Retrieving the current pixbuf via the #GstGdkPixbufSink:last-pixbuf property
 * when needed. This is the easiest way to get at pixbufs for snapshotting
 * purposes - just wait until the pipeline is prerolled (ASYNC_DONE message
 * on the bus), then read the property. If you use this method, you may want
 * to disable message posting by setting the #GstGdkPixbufSink:post-messages
 * property to #FALSE. This avoids unnecessary memory overhead.
 * </listitem>
 * </itemizedlist>
 *
 * The primary purpose of this element is to abstract away the #GstBuffer to
 * #GdkPixbuf conversion. Other than that it's very similar to the fakesink
 * element.
 *
 * This element is meant for easy no-hassle video snapshotting. It is not
 * suitable for video playback or video display at high framerates. Use
 * ximagesink, xvimagesink or some other suitable video sink in connection
 * with the #GstXOverlay interface instead if you want to do video playback.
 *
 * <refsect2>
 * <title>Message details</title>
 * As mentioned above, this element will by default post element messages
 * containing structures named <classname>&quot;preroll-pixbuf&quot;
 * </classname> or <classname>&quot;pixbuf&quot;</classname> on the bus (this
 * can be disabled by setting the #GstGdkPixbufSink:post-messages property
 * to #FALSE though). The element message structure has the following fields:
 * <itemizedlist>
 * <listitem>
 *   <classname>&quot;pixbuf&quot;</classname>: the #GdkPixbuf object
 * </listitem>
 * <listitem>
 *   <classname>&quot;pixel-aspect-ratio&quot;</classname>: the pixel aspect
 *   ratio (PAR) of the input image (this field contains a #GstFraction); the
 *   PAR is usually 1:1 for images, but is often something non-1:1 in the case
 *   of video input. In this case the image may be distorted and you may need
 *   to rescale it accordingly before saving it to file or displaying it. This
 *   can easily be done using gdk_pixbuf_scale() (the reason this is not done
 *   automatically is that the application will often scale the image anyway
 *   according to the size of the output window, in which case it is much more
 *   efficient to only scale once rather than twice). You can put a videoscale
 *   element and a capsfilter element with
 *   <literal>video/x-raw-rgb,pixel-aspect-ratio=(fraction)1/1</literal> caps
 *   in front of this element to make sure the pixbufs always have a 1:1 PAR.
 * </listitem>
 * </itemizedlist>
 * </refsect2>
 *
 * <refsect2>
 * <title>Example pipeline</title>
 * |[
 * gst-launch-1.0 -m -v videotestsrc num-buffers=1 ! gdkpixbufsink
 * ]| Process one single test image as pixbuf (note that the output you see will
 * be slightly misleading. The message structure does contain a valid pixbuf
 * object even if the structure string says &apos;(NULL)&apos;).
 * </refsect2>
 */

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

#include "gstgdkpixbufsink.h"

#include <gst/video/video.h>

#define DEFAULT_SEND_MESSAGES TRUE
#define DEFAULT_POST_MESSAGES TRUE

enum
{
  PROP_0,
  PROP_POST_MESSAGES,
  PROP_LAST_PIXBUF,
  PROP_LAST
};


G_DEFINE_TYPE (GstGdkPixbufSink, gst_gdk_pixbuf_sink, GST_TYPE_VIDEO_SINK);

static void gst_gdk_pixbuf_sink_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_gdk_pixbuf_sink_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);

static gboolean gst_gdk_pixbuf_sink_start (GstBaseSink * basesink);
static gboolean gst_gdk_pixbuf_sink_stop (GstBaseSink * basesink);
static gboolean gst_gdk_pixbuf_sink_set_caps (GstBaseSink * basesink,
    GstCaps * caps);
static GstFlowReturn gst_gdk_pixbuf_sink_render (GstBaseSink * bsink,
    GstBuffer * buf);
static GstFlowReturn gst_gdk_pixbuf_sink_preroll (GstBaseSink * bsink,
    GstBuffer * buf);
static GdkPixbuf *gst_gdk_pixbuf_sink_get_pixbuf_from_buffer (GstGdkPixbufSink *
    sink, GstBuffer * buf);

static GstStaticPadTemplate pixbufsink_sink_factory =
    GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("RGB") ";"
        GST_VIDEO_CAPS_MAKE ("RGBA"))
    );

static void
gst_gdk_pixbuf_sink_class_init (GstGdkPixbufSinkClass * klass)
{
  GstBaseSinkClass *basesink_class = GST_BASE_SINK_CLASS (klass);
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

  gst_element_class_set_static_metadata (element_class, "GdkPixbuf sink",
      "Sink/Video", "Output images as GdkPixbuf objects in bus messages",
      "Tim-Philipp Müller <tim centricular net>");

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&pixbufsink_sink_factory));

  gobject_class->set_property = gst_gdk_pixbuf_sink_set_property;
  gobject_class->get_property = gst_gdk_pixbuf_sink_get_property;

  /**
   * GstGdkPixbuf:post-messages:
   *
   * Post messages on the bus containing pixbufs.
   *
   * Since: 0.10.17
   */
  g_object_class_install_property (gobject_class, PROP_POST_MESSAGES,
      g_param_spec_boolean ("post-messages", "Post Messages",
          "Whether to post messages containing pixbufs on the bus",
          DEFAULT_POST_MESSAGES, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_LAST_PIXBUF,
      g_param_spec_object ("last-pixbuf", "Last Pixbuf",
          "Last GdkPixbuf object rendered", GDK_TYPE_PIXBUF,
          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));

  basesink_class->start = GST_DEBUG_FUNCPTR (gst_gdk_pixbuf_sink_start);
  basesink_class->stop = GST_DEBUG_FUNCPTR (gst_gdk_pixbuf_sink_stop);
  basesink_class->render = GST_DEBUG_FUNCPTR (gst_gdk_pixbuf_sink_render);
  basesink_class->preroll = GST_DEBUG_FUNCPTR (gst_gdk_pixbuf_sink_preroll);
  basesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_gdk_pixbuf_sink_set_caps);
}

static void
gst_gdk_pixbuf_sink_init (GstGdkPixbufSink * sink)
{
  sink->par_n = 0;
  sink->par_d = 0;
  sink->has_alpha = FALSE;
  sink->last_pixbuf = NULL;
  sink->post_messages = DEFAULT_POST_MESSAGES;

  /* we're not a real video sink, we just derive from GstVideoSink in case
   * anything interesting is added to it in future */
  gst_base_sink_set_max_lateness (GST_BASE_SINK (sink), -1);
  gst_base_sink_set_qos_enabled (GST_BASE_SINK (sink), FALSE);
}


static gboolean
gst_gdk_pixbuf_sink_start (GstBaseSink * basesink)
{
  GST_LOG_OBJECT (basesink, "start");

  return TRUE;
}

static gboolean
gst_gdk_pixbuf_sink_stop (GstBaseSink * basesink)
{
  GstGdkPixbufSink *sink = GST_GDK_PIXBUF_SINK (basesink);

  GST_VIDEO_SINK_WIDTH (sink) = 0;
  GST_VIDEO_SINK_HEIGHT (sink) = 0;

  sink->par_n = 0;
  sink->par_d = 0;
  sink->has_alpha = FALSE;

  if (sink->last_pixbuf) {
    g_object_unref (sink->last_pixbuf);
    sink->last_pixbuf = NULL;
  }

  GST_LOG_OBJECT (sink, "stop");

  return TRUE;
}

static gboolean
gst_gdk_pixbuf_sink_set_caps (GstBaseSink * basesink, GstCaps * caps)
{
  GstGdkPixbufSink *sink = GST_GDK_PIXBUF_SINK (basesink);
  GstVideoInfo info;
  GstVideoFormat fmt;
  gint w, h, s, par_n, par_d;

  GST_LOG_OBJECT (sink, "caps: %" GST_PTR_FORMAT, caps);

  if (!gst_video_info_from_caps (&info, caps)) {
    GST_WARNING_OBJECT (sink, "parse_caps failed");
    return FALSE;
  }

  fmt = GST_VIDEO_INFO_FORMAT (&info);
  w = GST_VIDEO_INFO_WIDTH (&info);
  h = GST_VIDEO_INFO_HEIGHT (&info);
  s = GST_VIDEO_INFO_COMP_PSTRIDE (&info, 0);
  par_n = GST_VIDEO_INFO_PAR_N (&info);
  par_d = GST_VIDEO_INFO_PAR_N (&info);

  g_assert ((fmt == GST_VIDEO_FORMAT_RGB && s == 3) ||
      (fmt == GST_VIDEO_FORMAT_RGBA && s == 4));

  GST_VIDEO_SINK_WIDTH (sink) = w;
  GST_VIDEO_SINK_HEIGHT (sink) = h;

  sink->par_n = par_n;
  sink->par_d = par_d;

  sink->has_alpha = GST_VIDEO_INFO_HAS_ALPHA (&info);

  GST_INFO_OBJECT (sink, "format             : %d", fmt);
  GST_INFO_OBJECT (sink, "width x height     : %d x %d", w, h);
  GST_INFO_OBJECT (sink, "pixel-aspect-ratio : %d/%d", par_n, par_d);

  sink->info = info;

  return TRUE;
}

static void
gst_gdk_pixbuf_sink_pixbuf_destroy_notify (guchar * pixels,
    GstVideoFrame * frame)
{
  gst_video_frame_unmap (frame);
  gst_buffer_unref (frame->buffer);
  g_slice_free (GstVideoFrame, frame);
}

static GdkPixbuf *
gst_gdk_pixbuf_sink_get_pixbuf_from_buffer (GstGdkPixbufSink * sink,
    GstBuffer * buf)
{
  GdkPixbuf *pix = NULL;
  GstVideoFrame *frame;
  gint minsize, bytes_per_pixel;

  g_return_val_if_fail (GST_VIDEO_SINK_WIDTH (sink) > 0, NULL);
  g_return_val_if_fail (GST_VIDEO_SINK_HEIGHT (sink) > 0, NULL);

  frame = g_slice_new0 (GstVideoFrame);
  gst_video_frame_map (frame, &sink->info, buf, GST_MAP_READ);

  bytes_per_pixel = (sink->has_alpha) ? 4 : 3;

  /* last row needn't have row padding */
  minsize = (GST_VIDEO_FRAME_COMP_STRIDE (frame, 0) *
      (GST_VIDEO_SINK_HEIGHT (sink) - 1)) +
      (bytes_per_pixel * GST_VIDEO_SINK_WIDTH (sink));

  g_return_val_if_fail (gst_buffer_get_size (buf) >= minsize, NULL);

  gst_buffer_ref (buf);
  pix = gdk_pixbuf_new_from_data (GST_VIDEO_FRAME_COMP_DATA (frame, 0),
      GDK_COLORSPACE_RGB, sink->has_alpha, 8, GST_VIDEO_SINK_WIDTH (sink),
      GST_VIDEO_SINK_HEIGHT (sink), GST_VIDEO_FRAME_COMP_STRIDE (frame, 0),
      (GdkPixbufDestroyNotify) gst_gdk_pixbuf_sink_pixbuf_destroy_notify,
      frame);

  return pix;
}

static GstFlowReturn
gst_gdk_pixbuf_sink_handle_buffer (GstBaseSink * basesink, GstBuffer * buf,
    const gchar * msg_name)
{
  GstGdkPixbufSink *sink;
  GdkPixbuf *pixbuf;
  gboolean do_post;

  sink = GST_GDK_PIXBUF_SINK (basesink);

  pixbuf = gst_gdk_pixbuf_sink_get_pixbuf_from_buffer (sink, buf);

  GST_OBJECT_LOCK (sink);

  do_post = sink->post_messages;

  if (sink->last_pixbuf)
    g_object_unref (sink->last_pixbuf);

  sink->last_pixbuf = pixbuf;   /* take ownership */

  GST_OBJECT_UNLOCK (sink);

  if (G_UNLIKELY (pixbuf == NULL))
    goto error;

  if (do_post) {
    GstStructure *s;
    GstMessage *msg;
    GstFormat format;
    GstClockTime timestamp;
    GstClockTime running_time, stream_time;

    GstSegment *segment = &basesink->segment;
    format = segment->format;

    timestamp = GST_BUFFER_PTS (buf);
    running_time = gst_segment_to_running_time (segment, format, timestamp);
    stream_time = gst_segment_to_stream_time (segment, format, timestamp);

    /* it's okay to keep using pixbuf here, we can be sure no one is going to
     * unref or change sink->last_pixbuf before we return from this function.
     * The structure will take its own ref to the pixbuf. */
    s = gst_structure_new (msg_name,
        "pixbuf", GDK_TYPE_PIXBUF, pixbuf,
        "pixel-aspect-ratio", GST_TYPE_FRACTION, sink->par_n, sink->par_d,
        "timestamp", G_TYPE_UINT64, timestamp,
        "stream-time", G_TYPE_UINT64, stream_time,
        "running-time", G_TYPE_UINT64, running_time, NULL);

    msg = gst_message_new_element (GST_OBJECT_CAST (sink), s);
    gst_element_post_message (GST_ELEMENT_CAST (sink), msg);
  }

  g_object_notify (G_OBJECT (sink), "last-pixbuf");

  return GST_FLOW_OK;

/* ERRORS */
error:
  {
    /* This shouldn't really happen */
    GST_ELEMENT_ERROR (sink, LIBRARY, FAILED,
        ("Couldn't create pixbuf from RGB image."),
        ("Probably not enough free memory"));
    return GST_FLOW_ERROR;
  }
}

static GstFlowReturn
gst_gdk_pixbuf_sink_preroll (GstBaseSink * basesink, GstBuffer * buf)
{
  return gst_gdk_pixbuf_sink_handle_buffer (basesink, buf, "preroll-pixbuf");
}

static GstFlowReturn
gst_gdk_pixbuf_sink_render (GstBaseSink * basesink, GstBuffer * buf)
{
  return gst_gdk_pixbuf_sink_handle_buffer (basesink, buf, "pixbuf");
}

static void
gst_gdk_pixbuf_sink_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstGdkPixbufSink *sink;

  sink = GST_GDK_PIXBUF_SINK (object);

  switch (prop_id) {
    case PROP_POST_MESSAGES:
      GST_OBJECT_LOCK (sink);
      sink->post_messages = g_value_get_boolean (value);
      GST_OBJECT_UNLOCK (sink);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_gdk_pixbuf_sink_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstGdkPixbufSink *sink;

  sink = GST_GDK_PIXBUF_SINK (object);

  switch (prop_id) {
    case PROP_POST_MESSAGES:
      GST_OBJECT_LOCK (sink);
      g_value_set_boolean (value, sink->post_messages);
      GST_OBJECT_UNLOCK (sink);
      break;
    case PROP_LAST_PIXBUF:
      GST_OBJECT_LOCK (sink);
      g_value_set_object (value, sink->last_pixbuf);
      GST_OBJECT_UNLOCK (sink);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}
