/* GStreamer
 * Copyright (C) 2010 Sebastian Dröge <sebastian.droege@collabora.co.uk>
 *
 * 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.
 */

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

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

#include "gstvideosegmentclip.h"

static GstStaticPadTemplate sink_pad_template =
GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("video/x-raw, framerate=" GST_VIDEO_FPS_RANGE));

static GstStaticPadTemplate src_pad_template =
GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("video/x-raw, framerate=" GST_VIDEO_FPS_RANGE));

static void gst_video_segment_clip_reset (GstSegmentClip * self);
static GstFlowReturn gst_video_segment_clip_clip_buffer (GstSegmentClip * self,
    GstBuffer * buffer, GstBuffer ** outbuf);
static gboolean gst_video_segment_clip_set_caps (GstSegmentClip * self,
    GstCaps * caps);

GST_DEBUG_CATEGORY_STATIC (gst_video_segment_clip_debug);
#define GST_CAT_DEFAULT gst_video_segment_clip_debug

G_DEFINE_TYPE (GstVideoSegmentClip, gst_video_segment_clip,
    GST_TYPE_SEGMENT_CLIP);

static void
gst_video_segment_clip_class_init (GstVideoSegmentClipClass * klass)
{
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
  GstSegmentClipClass *segment_clip_klass = GST_SEGMENT_CLIP_CLASS (klass);

  GST_DEBUG_CATEGORY_INIT (gst_video_segment_clip_debug, "videosegmentclip", 0,
      "videosegmentclip element");

  gst_element_class_set_static_metadata (element_class,
      "Video buffer segment clipper",
      "Filter/Video",
      "Clips video buffers to the configured segment",
      "Sebastian Dröge <sebastian.droege@collabora.co.uk>");

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&sink_pad_template));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&src_pad_template));

  segment_clip_klass->reset = GST_DEBUG_FUNCPTR (gst_video_segment_clip_reset);
  segment_clip_klass->set_caps =
      GST_DEBUG_FUNCPTR (gst_video_segment_clip_set_caps);
  segment_clip_klass->clip_buffer =
      GST_DEBUG_FUNCPTR (gst_video_segment_clip_clip_buffer);
}

static void
gst_video_segment_clip_init (GstVideoSegmentClip * self)
{
}

static void
gst_video_segment_clip_reset (GstSegmentClip * base)
{
  GstVideoSegmentClip *self = GST_VIDEO_SEGMENT_CLIP (base);

  GST_DEBUG_OBJECT (self, "Resetting internal state");

  self->fps_n = self->fps_d = 0;
}


static GstFlowReturn
gst_video_segment_clip_clip_buffer (GstSegmentClip * base, GstBuffer * buffer,
    GstBuffer ** outbuf)
{
  GstVideoSegmentClip *self = GST_VIDEO_SEGMENT_CLIP (base);
  GstSegment *segment = &base->segment;
  GstClockTime timestamp, duration;
  guint64 cstart, cstop;
  gboolean in_seg;

  if (!self->fps_d) {
    GST_ERROR_OBJECT (self, "Not negotiated yet");
    gst_buffer_unref (buffer);
    return GST_FLOW_NOT_NEGOTIATED;
  }

  if (segment->format != GST_FORMAT_TIME) {
    GST_DEBUG_OBJECT (self, "Unsupported segment format %s",
        gst_format_get_name (segment->format));
    *outbuf = buffer;
    return GST_FLOW_OK;
  }

  if (!GST_BUFFER_TIMESTAMP_IS_VALID (buffer)) {
    GST_WARNING_OBJECT (self, "Buffer without valid timestamp");
    *outbuf = buffer;
    return GST_FLOW_OK;
  }

  if (self->fps_n == 0) {
    *outbuf = buffer;
    return GST_FLOW_OK;
  }

  timestamp = GST_BUFFER_TIMESTAMP (buffer);
  duration = GST_BUFFER_DURATION (buffer);
  if (!GST_CLOCK_TIME_IS_VALID (duration))
    duration = gst_util_uint64_scale (GST_SECOND, self->fps_d, self->fps_n);

  in_seg =
      gst_segment_clip (segment, GST_FORMAT_TIME, timestamp,
      timestamp + duration, &cstart, &cstop);
  if (in_seg) {
    if (timestamp != cstart || timestamp + duration != cstop) {
      *outbuf = gst_buffer_make_writable (buffer);

      GST_BUFFER_TIMESTAMP (*outbuf) = cstart;
      GST_BUFFER_DURATION (*outbuf) = cstop - cstart;
    } else {
      *outbuf = buffer;
    }
  } else {
    GST_DEBUG_OBJECT (self, "Buffer outside the configured segment");

    gst_buffer_unref (buffer);
    if (segment->rate >= 0) {
      if (segment->stop != -1 && timestamp >= segment->stop)
        return GST_FLOW_EOS;
    } else {
      if (segment->start != -1 && timestamp + duration <= segment->start)
        return GST_FLOW_EOS;
    }
  }


  return GST_FLOW_OK;
}

static gboolean
gst_video_segment_clip_set_caps (GstSegmentClip * base, GstCaps * caps)
{
  GstVideoSegmentClip *self = GST_VIDEO_SEGMENT_CLIP (base);
  gboolean ret;
  GstStructure *s;
  gint fps_n, fps_d;

  s = gst_caps_get_structure (caps, 0);

  ret = gst_structure_get_fraction (s, "framerate", &fps_n, &fps_d)
      && (fps_d != 0);

  if (ret) {
    GST_DEBUG_OBJECT (self, "Configured framerate %d/%d", fps_n, fps_d);
    self->fps_n = fps_n;
    self->fps_d = fps_d;
  }

  return ret;
}
