/* GStreamer
 * Copyright (C) 2013 FIXME <fixme@example.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 Street, Suite 500,
 * Boston, MA 02110-1335, USA.
 */
/**
 * SECTION:element-gstvideodiff
 *
 * The videodiff element does FIXME stuff.
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch-1.0 -v fakesrc ! videodiff ! FIXME ! fakesink
 * ]|
 * FIXME Describe what the pipeline does.
 * </refsect2>
 */

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

#include <gst/gst.h>
#include <gst/video/video.h>
#include <gst/video/gstvideofilter.h>
#include "gstvideodiff.h"

GST_DEBUG_CATEGORY_STATIC (gst_video_diff_debug_category);
#define GST_CAT_DEFAULT gst_video_diff_debug_category

/* prototypes */

static GstFlowReturn gst_video_diff_transform_frame (GstVideoFilter * filter,
    GstVideoFrame * inframe, GstVideoFrame * outframe);

enum
{
  PROP_0
};

/* pad templates */

/* FIXME: add/remove formats you can handle */
#define VIDEO_SRC_CAPS \
    GST_VIDEO_CAPS_MAKE("{ I420, Y444, Y42B, UYVY, RGBA }")

/* FIXME: add/remove formats you can handle */
#define VIDEO_SINK_CAPS \
    GST_VIDEO_CAPS_MAKE("{ I420, Y444, Y42B, UYVY, RGBA }")


/* class initialization */

G_DEFINE_TYPE_WITH_CODE (GstVideoDiff, gst_video_diff, GST_TYPE_VIDEO_FILTER,
    GST_DEBUG_CATEGORY_INIT (gst_video_diff_debug_category, "videodiff", 0,
        "debug category for videodiff element"));

static void
gst_video_diff_class_init (GstVideoDiffClass * klass)
{
  GstVideoFilterClass *video_filter_class = GST_VIDEO_FILTER_CLASS (klass);

  /* Setting up pads and setting metadata should be moved to
     base_class_init if you intend to subclass this class. */
  gst_element_class_add_pad_template (GST_ELEMENT_CLASS (klass),
      gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
          gst_caps_from_string (VIDEO_SRC_CAPS)));
  gst_element_class_add_pad_template (GST_ELEMENT_CLASS (klass),
      gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
          gst_caps_from_string (VIDEO_SINK_CAPS)));

  gst_element_class_set_static_metadata (GST_ELEMENT_CLASS (klass),
      "FIXME Long name", "Generic", "FIXME Description",
      "FIXME <fixme@example.com>");

  video_filter_class->transform_frame =
      GST_DEBUG_FUNCPTR (gst_video_diff_transform_frame);

}

static void
gst_video_diff_init (GstVideoDiff * videodiff)
{
  videodiff->threshold = 10;
}

static GstFlowReturn
gst_video_diff_transform_frame_ip_planarY (GstVideoDiff * videodiff,
    GstVideoFrame * outframe, GstVideoFrame * inframe, GstVideoFrame * oldframe)
{
  int width = inframe->info.width;
  int height = inframe->info.height;
  int i, j;
  int threshold = videodiff->threshold;
  int t = videodiff->t;

  for (j = 0; j < height; j++) {
    guint8 *d = (guint8 *) outframe->data[0] + outframe->info.stride[0] * j;
    guint8 *s1 = (guint8 *) oldframe->data[0] + oldframe->info.stride[0] * j;
    guint8 *s2 = (guint8 *) inframe->data[0] + inframe->info.stride[0] * j;
    for (i = 0; i < width; i++) {
      if ((s2[i] < s1[i] - threshold) || (s2[i] > s1[i] + threshold)) {
        if ((i + j + t) & 0x4) {
          d[i] = 16;
        } else {
          d[i] = 240;
        }
      } else {
        d[i] = s2[i];
      }
    }
  }
  for (j = 0; j < GST_VIDEO_FRAME_COMP_HEIGHT (inframe, 1); j++) {
    guint8 *d = (guint8 *) outframe->data[1] + outframe->info.stride[1] * j;
    guint8 *s = (guint8 *) inframe->data[1] + inframe->info.stride[1] * j;
    memcpy (d, s, GST_VIDEO_FRAME_COMP_WIDTH (inframe, 1));
  }
  for (j = 0; j < GST_VIDEO_FRAME_COMP_HEIGHT (inframe, 2); j++) {
    guint8 *d = (guint8 *) outframe->data[2] + outframe->info.stride[2] * j;
    guint8 *s = (guint8 *) inframe->data[2] + inframe->info.stride[2] * j;
    memcpy (d, s, GST_VIDEO_FRAME_COMP_WIDTH (inframe, 2));
  }
  return GST_FLOW_OK;
}

static GstFlowReturn
gst_video_diff_transform_frame (GstVideoFilter * filter,
    GstVideoFrame * inframe, GstVideoFrame * outframe)
{
  GstVideoDiff *videodiff = GST_VIDEO_DIFF (filter);

  GST_DEBUG_OBJECT (videodiff, "transform_frame_ip");

  if (videodiff->previous_buffer) {
    GstVideoFrame oldframe;

    gst_video_frame_map (&oldframe, &videodiff->oldinfo,
        videodiff->previous_buffer, GST_MAP_READ);

    switch (inframe->info.finfo->format) {
      case GST_VIDEO_FORMAT_I420:
      case GST_VIDEO_FORMAT_Y41B:
      case GST_VIDEO_FORMAT_Y444:
      case GST_VIDEO_FORMAT_Y42B:
        gst_video_diff_transform_frame_ip_planarY (videodiff, outframe,
            inframe, &oldframe);
        break;
      default:
        g_assert_not_reached ();
    }

    gst_video_frame_unmap (&oldframe);
    gst_buffer_unref (videodiff->previous_buffer);
  } else {
    int k;
    int j;
    for (k = 0; k < 3; k++) {
      for (j = 0; j < GST_VIDEO_FRAME_COMP_HEIGHT (inframe, k); j++) {
        guint8 *d = (guint8 *) outframe->data[k] + outframe->info.stride[k] * j;
        guint8 *s = (guint8 *) inframe->data[k] + inframe->info.stride[k] * j;
        memcpy (d, s, GST_VIDEO_FRAME_COMP_WIDTH (inframe, k));
      }
    }
  }

  videodiff->previous_buffer = gst_buffer_ref (inframe->buffer);
  memcpy (&videodiff->oldinfo, &inframe->info, sizeof (GstVideoInfo));

  return GST_FLOW_OK;
}
