/* GStreamer fbdev plugin
 * Copyright (C) 2007 Sean D'Epagnier <sean@depagnier.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.
 */

/* currently the driver does not switch modes, instead uses current mode.
   the video is centered and cropped if needed to fit onscreen.
   Whatever bitdepth is set is used, and tested to work for 16, 24, 32 bits
*/

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

#include <signal.h>
#include <string.h>
#include <sys/time.h>
#include <stdlib.h>

#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <unistd.h>
#include "_stdint.h"

#include "gstfbdevsink.h"

enum
{
  ARG_0,
  ARG_DEVICE
};

#if 0
static void gst_fbdevsink_get_times (GstBaseSink * basesink,
    GstBuffer * buffer, GstClockTime * start, GstClockTime * end);
#endif

static GstFlowReturn gst_fbdevsink_show_frame (GstVideoSink * videosink,
    GstBuffer * buff);

static gboolean gst_fbdevsink_start (GstBaseSink * bsink);
static gboolean gst_fbdevsink_stop (GstBaseSink * bsink);

static GstCaps *gst_fbdevsink_getcaps (GstBaseSink * bsink, GstCaps * filter);
static gboolean gst_fbdevsink_setcaps (GstBaseSink * bsink, GstCaps * caps);

static void gst_fbdevsink_finalize (GObject * object);
static void gst_fbdevsink_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec);
static void gst_fbdevsink_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec);
static GstStateChangeReturn gst_fbdevsink_change_state (GstElement * element,
    GstStateChange transition);

#define VIDEO_CAPS "{ RGB, BGR, BGRx, xBGR, RGB, RGBx, xRGB, RGB15, RGB16 }"

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

#define parent_class gst_fbdevsink_parent_class
G_DEFINE_TYPE (GstFBDEVSink, gst_fbdevsink, GST_TYPE_VIDEO_SINK);

static void
gst_fbdevsink_init (GstFBDEVSink * fbdevsink)
{
  /* nothing to do here yet */
}

#if 0
static void
gst_fbdevsink_get_times (GstBaseSink * basesink, GstBuffer * buffer,
    GstClockTime * start, GstClockTime * end)
{
  GstFBDEVSink *fbdevsink;

  fbdevsink = GST_FBDEVSINK (basesink);

  if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer)) {
    *start = GST_BUFFER_TIMESTAMP (buffer);
    if (GST_BUFFER_DURATION_IS_VALID (buffer)) {
      *end = *start + GST_BUFFER_DURATION (buffer);
    } else {
      if (fbdevsink->fps_n > 0) {
        *end = *start +
            gst_util_uint64_scale_int (GST_SECOND, fbdevsink->fps_d,
            fbdevsink->fps_n);
      }
    }
  }
}
#endif

static GstCaps *
gst_fbdevsink_getcaps (GstBaseSink * bsink, GstCaps * filter)
{
  GstFBDEVSink *fbdevsink;
  GstVideoFormat format;
  GstCaps *caps;
  uint32_t rmask;
  uint32_t gmask;
  uint32_t bmask;
  uint32_t tmask;
  int endianness, depth, bpp;

  fbdevsink = GST_FBDEVSINK (bsink);

  caps = gst_static_pad_template_get_caps (&sink_template);

  /* FIXME: locking */
  if (!fbdevsink->framebuffer)
    goto done;

  bpp = fbdevsink->varinfo.bits_per_pixel;

  rmask = ((1 << fbdevsink->varinfo.red.length) - 1)
      << fbdevsink->varinfo.red.offset;
  gmask = ((1 << fbdevsink->varinfo.green.length) - 1)
      << fbdevsink->varinfo.green.offset;
  bmask = ((1 << fbdevsink->varinfo.blue.length) - 1)
      << fbdevsink->varinfo.blue.offset;
  tmask = ((1 << fbdevsink->varinfo.transp.length) - 1)
      << fbdevsink->varinfo.transp.offset;

  depth = fbdevsink->varinfo.red.length + fbdevsink->varinfo.green.length
      + fbdevsink->varinfo.blue.length;

  switch (fbdevsink->varinfo.bits_per_pixel) {
    case 32:
      /* swap endianness of masks */
      rmask = GUINT32_SWAP_LE_BE (rmask);
      gmask = GUINT32_SWAP_LE_BE (gmask);
      bmask = GUINT32_SWAP_LE_BE (bmask);
      tmask = GUINT32_SWAP_LE_BE (tmask);
      depth += fbdevsink->varinfo.transp.length;
      endianness = G_BIG_ENDIAN;
      break;
    case 24:{
      /* swap red and blue masks */
      tmask = rmask;
      rmask = bmask;
      bmask = tmask;
      tmask = 0;
      endianness = G_BIG_ENDIAN;
      break;
    }
    case 15:
    case 16:
      tmask = 0;
      endianness = G_LITTLE_ENDIAN;
      break;
    default:
      goto unsupported_bpp;
  }

  format = gst_video_format_from_masks (depth, bpp, endianness, rmask, gmask,
      bmask, tmask);

  if (format == GST_VIDEO_FORMAT_UNKNOWN)
    goto unknown_format;

  caps = gst_caps_make_writable (caps);
  gst_caps_set_simple (caps, "format", G_TYPE_STRING,
      gst_video_format_to_string (format), NULL);

done:

  if (filter != NULL) {
    GstCaps *icaps;

    icaps = gst_caps_intersect (caps, filter);
    gst_caps_unref (caps);
    caps = icaps;
  }

  return caps;

/* ERRORS */
unsupported_bpp:
  {
    GST_WARNING_OBJECT (bsink, "unsupported bit depth: %d", bpp);
    return NULL;
  }
unknown_format:
  {
    GST_WARNING_OBJECT (bsink, "could not map fbdev format to GstVideoFormat: "
        "depth=%u, bpp=%u, endianness=%u, rmask=0x%08x, gmask=0x%08x, "
        "bmask=0x%08x, tmask=0x%08x", depth, bpp, endianness, rmask, gmask,
        bmask, tmask);
    return NULL;
  }
}

static gboolean
gst_fbdevsink_setcaps (GstBaseSink * bsink, GstCaps * vscapslist)
{
  GstFBDEVSink *fbdevsink;
  GstStructure *structure;
  const GValue *fps;

  fbdevsink = GST_FBDEVSINK (bsink);

  structure = gst_caps_get_structure (vscapslist, 0);

  fps = gst_structure_get_value (structure, "framerate");
  fbdevsink->fps_n = gst_value_get_fraction_numerator (fps);
  fbdevsink->fps_d = gst_value_get_fraction_denominator (fps);

  gst_structure_get_int (structure, "width", &fbdevsink->width);
  gst_structure_get_int (structure, "height", &fbdevsink->height);

  /* calculate centering and scanlengths for the video */
  fbdevsink->bytespp = fbdevsink->fixinfo.line_length / fbdevsink->varinfo.xres;

  fbdevsink->cx = ((int) fbdevsink->varinfo.xres - fbdevsink->width) / 2;
  if (fbdevsink->cx < 0)
    fbdevsink->cx = 0;

  fbdevsink->cy = ((int) fbdevsink->varinfo.yres - fbdevsink->height) / 2;
  if (fbdevsink->cy < 0)
    fbdevsink->cy = 0;

  fbdevsink->linelen = fbdevsink->width * fbdevsink->bytespp;
  if (fbdevsink->linelen > fbdevsink->fixinfo.line_length)
    fbdevsink->linelen = fbdevsink->fixinfo.line_length;

  fbdevsink->lines = fbdevsink->height;
  if (fbdevsink->lines > fbdevsink->varinfo.yres)
    fbdevsink->lines = fbdevsink->varinfo.yres;

  return TRUE;
}


static GstFlowReturn
gst_fbdevsink_show_frame (GstVideoSink * videosink, GstBuffer * buf)
{

  GstFBDEVSink *fbdevsink;
  GstMapInfo map;
  int i;

  fbdevsink = GST_FBDEVSINK (videosink);

  /* optimization could remove this memcpy by allocating the buffer
     in framebuffer memory, but would only work when xres matches
     the video width */
  if (!gst_buffer_map (buf, &map, GST_MAP_READ))
    return GST_FLOW_ERROR;

  for (i = 0; i < fbdevsink->lines; i++) {
    memcpy (fbdevsink->framebuffer
        + (i + fbdevsink->cy) * fbdevsink->fixinfo.line_length
        + fbdevsink->cx * fbdevsink->bytespp,
        map.data + i * fbdevsink->width * fbdevsink->bytespp,
        fbdevsink->linelen);
  }

  gst_buffer_unmap (buf, &map);

  return GST_FLOW_OK;
}

static gboolean
gst_fbdevsink_start (GstBaseSink * bsink)
{
  GstFBDEVSink *fbdevsink;

  fbdevsink = GST_FBDEVSINK (bsink);

  if (!fbdevsink->device) {
    fbdevsink->device = g_strdup ("/dev/fb0");
  }

  fbdevsink->fd = open (fbdevsink->device, O_RDWR);

  if (fbdevsink->fd == -1)
    return FALSE;

  /* get the fixed screen info */
  if (ioctl (fbdevsink->fd, FBIOGET_FSCREENINFO, &fbdevsink->fixinfo))
    return FALSE;

  /* get the variable screen info */
  if (ioctl (fbdevsink->fd, FBIOGET_VSCREENINFO, &fbdevsink->varinfo))
    return FALSE;

  /* map the framebuffer */
  fbdevsink->framebuffer = mmap (0, fbdevsink->fixinfo.smem_len,
      PROT_WRITE, MAP_SHARED, fbdevsink->fd, 0);
  if (fbdevsink->framebuffer == MAP_FAILED)
    return FALSE;

  return TRUE;
}

static gboolean
gst_fbdevsink_stop (GstBaseSink * bsink)
{
  GstFBDEVSink *fbdevsink;

  fbdevsink = GST_FBDEVSINK (bsink);

  if (munmap (fbdevsink->framebuffer, fbdevsink->fixinfo.smem_len))
    return FALSE;

  if (close (fbdevsink->fd))
    return FALSE;


  return TRUE;
}

static void
gst_fbdevsink_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstFBDEVSink *fbdevsink;

  fbdevsink = GST_FBDEVSINK (object);

  switch (prop_id) {
    case ARG_DEVICE:{
      g_free (fbdevsink->device);
      fbdevsink->device = g_value_dup_string (value);
      break;
    }
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}


static void
gst_fbdevsink_get_property (GObject * object, guint prop_id, GValue * value,
    GParamSpec * pspec)
{
  GstFBDEVSink *fbdevsink;

  fbdevsink = GST_FBDEVSINK (object);

  switch (prop_id) {
    case ARG_DEVICE:{
      g_value_set_string (value, fbdevsink->device);
      break;
    }
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static GstStateChangeReturn
gst_fbdevsink_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;

  g_return_val_if_fail (GST_IS_FBDEVSINK (element), GST_STATE_CHANGE_FAILURE);

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

  switch (transition) {
    default:
      break;
  }
  return ret;
}

static gboolean
plugin_init (GstPlugin * plugin)
{
  if (!gst_element_register (plugin, "fbdevsink", GST_RANK_NONE,
          GST_TYPE_FBDEVSINK))
    return FALSE;

  return TRUE;
}

static void
gst_fbdevsink_class_init (GstFBDEVSinkClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
  GstBaseSinkClass *basesink_class;
  GstVideoSinkClass *videosink_class;

  gobject_class = (GObjectClass *) klass;
  gstelement_class = (GstElementClass *) klass;
  basesink_class = (GstBaseSinkClass *) klass;
  videosink_class = (GstVideoSinkClass *) klass;

  gobject_class->set_property = gst_fbdevsink_set_property;
  gobject_class->get_property = gst_fbdevsink_get_property;
  gobject_class->finalize = gst_fbdevsink_finalize;

  gstelement_class->change_state =
      GST_DEBUG_FUNCPTR (gst_fbdevsink_change_state);

  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DEVICE,
      g_param_spec_string ("device", "device",
          "The framebuffer device eg: /dev/fb0", NULL, G_PARAM_READWRITE));

  basesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_fbdevsink_setcaps);
  basesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_fbdevsink_getcaps);
#if 0
  basesink_class->get_times = GST_DEBUG_FUNCPTR (gst_fbdevsink_get_times);
#endif
  basesink_class->start = GST_DEBUG_FUNCPTR (gst_fbdevsink_start);
  basesink_class->stop = GST_DEBUG_FUNCPTR (gst_fbdevsink_stop);

  videosink_class->show_frame = GST_DEBUG_FUNCPTR (gst_fbdevsink_show_frame);

  gst_element_class_set_static_metadata (gstelement_class, "fbdev video sink",
      "Sink/Video", "Linux framebuffer videosink",
      "Sean D'Epagnier <sean@depagnier.com>");

  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&sink_template));
}

static void
gst_fbdevsink_finalize (GObject * object)
{
  GstFBDEVSink *fbdevsink = GST_FBDEVSINK (object);

  g_free (fbdevsink->device);

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

GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
    GST_VERSION_MINOR,
    fbdevsink,
    "Linux framebuffer video sink",
    plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
