/* GStreamer
 * Copyright (C) 2010 David Schleef <ds@schleef.org>
 *
 * 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-gstchopmydata
 *
 * The chopmydata element takes an incoming stream and chops it up
 * into randomly sized buffers.  Size of outgoing buffers are determined
 * by the max-size, min-size, and step-size properties.
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch -v audiotestsrc num-buffers=10 ! gstchopmydata min-size=100
 * max-size=200 step-size=2 ! fakesink -v
 * ]|
 * 
 * This pipeline will create 10 buffers that are by default 2048 bytes
 * each (1024 samples each), and chop them up into buffers that range
 * in size from 100 bytes to 200 bytes, with the restriction that sizes
 * are a multiple of 2.  This restriction is important, because the
 * default sample size for audiotestsrc is 2 bytes (one channel, 16-bit
 * audio).
 * 
 * </refsect2>
 */

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

#include <gst/gst.h>
#include <gst/gst.h>
#include "gstchopmydata.h"

/* prototypes */


static void gst_chop_my_data_set_property (GObject * object,
    guint property_id, const GValue * value, GParamSpec * pspec);
static void gst_chop_my_data_get_property (GObject * object,
    guint property_id, GValue * value, GParamSpec * pspec);

static GstStateChangeReturn
gst_chop_my_data_change_state (GstElement * element, GstStateChange transition);

static GstFlowReturn gst_chop_my_data_chain (GstPad * pad, GstObject * parent,
    GstBuffer * buffer);
static gboolean gst_chop_my_data_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event);
static gboolean gst_chop_my_data_src_event (GstPad * pad, GstObject * parent,
    GstEvent * event);

#define DEFAULT_MAX_SIZE 4096
#define DEFAULT_MIN_SIZE 1
#define DEFAULT_STEP_SIZE 1

enum
{
  PROP_0,
  PROP_MAX_SIZE,
  PROP_MIN_SIZE,
  PROP_STEP_SIZE
};

/* pad templates */

static GstStaticPadTemplate gst_chop_my_data_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS_ANY);

static GstStaticPadTemplate gst_chop_my_data_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS_ANY);

/* class initialization */

#define gst_chop_my_data_parent_class parent_class
G_DEFINE_TYPE (GstChopMyData, gst_chop_my_data, GST_TYPE_ELEMENT);

static void
gst_chop_my_data_class_init (GstChopMyDataClass * klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);

  gobject_class->set_property = gst_chop_my_data_set_property;
  gobject_class->get_property = gst_chop_my_data_get_property;
  element_class->change_state =
      GST_DEBUG_FUNCPTR (gst_chop_my_data_change_state);

  g_object_class_install_property (gobject_class, PROP_MAX_SIZE,
      g_param_spec_int ("max-size", "max-size",
          "Maximum size of outgoing buffers", 1, G_MAXINT,
          DEFAULT_MAX_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_MIN_SIZE,
      g_param_spec_int ("min-size", "max-size",
          "Minimum size of outgoing buffers", 1, G_MAXINT,
          DEFAULT_MIN_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_STEP_SIZE,
      g_param_spec_int ("step-size", "step-size",
          "Step increment for random buffer sizes", 1, G_MAXINT,
          DEFAULT_MAX_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&gst_chop_my_data_src_template));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&gst_chop_my_data_sink_template));

  gst_element_class_set_static_metadata (element_class, "FIXME",
      "Generic", "FIXME", "David Schleef <ds@schleef.org>");
}

static void
gst_chop_my_data_init (GstChopMyData * chopmydata)
{

  chopmydata->sinkpad =
      gst_pad_new_from_static_template (&gst_chop_my_data_sink_template,
      "sink");
  gst_pad_set_event_function (chopmydata->sinkpad,
      GST_DEBUG_FUNCPTR (gst_chop_my_data_sink_event));
  gst_pad_set_chain_function (chopmydata->sinkpad,
      GST_DEBUG_FUNCPTR (gst_chop_my_data_chain));
  GST_PAD_SET_PROXY_CAPS (chopmydata->sinkpad);
  gst_element_add_pad (GST_ELEMENT (chopmydata), chopmydata->sinkpad);

  chopmydata->srcpad =
      gst_pad_new_from_static_template (&gst_chop_my_data_src_template, "src");
  gst_pad_set_event_function (chopmydata->srcpad,
      GST_DEBUG_FUNCPTR (gst_chop_my_data_src_event));
  GST_PAD_SET_PROXY_CAPS (chopmydata->srcpad);
  gst_element_add_pad (GST_ELEMENT (chopmydata), chopmydata->srcpad);

  chopmydata->step_size = DEFAULT_STEP_SIZE;
  chopmydata->min_size = DEFAULT_MIN_SIZE;
  chopmydata->max_size = DEFAULT_MAX_SIZE;
}

void
gst_chop_my_data_set_property (GObject * object, guint property_id,
    const GValue * value, GParamSpec * pspec)
{
  GstChopMyData *chopmydata;

  g_return_if_fail (GST_IS_CHOP_MY_DATA (object));
  chopmydata = GST_CHOP_MY_DATA (object);

  switch (property_id) {
    case PROP_MAX_SIZE:
      chopmydata->max_size = g_value_get_int (value);
      break;
    case PROP_MIN_SIZE:
      chopmydata->min_size = g_value_get_int (value);
      break;
    case PROP_STEP_SIZE:
      chopmydata->step_size = g_value_get_int (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
  }
}

void
gst_chop_my_data_get_property (GObject * object, guint property_id,
    GValue * value, GParamSpec * pspec)
{
  GstChopMyData *chopmydata;

  g_return_if_fail (GST_IS_CHOP_MY_DATA (object));
  chopmydata = GST_CHOP_MY_DATA (object);

  switch (property_id) {
    case PROP_MAX_SIZE:
      g_value_set_int (value, chopmydata->max_size);
      break;
    case PROP_MIN_SIZE:
      g_value_set_int (value, chopmydata->min_size);
      break;
    case PROP_STEP_SIZE:
      g_value_set_int (value, chopmydata->step_size);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
  }
}

static GstStateChangeReturn
gst_chop_my_data_change_state (GstElement * element, GstStateChange transition)
{
  GstChopMyData *chopmydata;
  GstStateChangeReturn ret;

  chopmydata = GST_CHOP_MY_DATA (element);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      GST_OBJECT_LOCK (chopmydata);
      chopmydata->adapter = gst_adapter_new ();
      chopmydata->rand = g_rand_new ();
      chopmydata->next_size = 0;
      GST_OBJECT_UNLOCK (chopmydata);
      break;
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      break;
    default:
      break;
  }

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

  switch (transition) {
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      GST_OBJECT_LOCK (chopmydata);
      g_object_unref (chopmydata->adapter);
      chopmydata->adapter = NULL;
      g_rand_free (chopmydata->rand);
      GST_OBJECT_UNLOCK (chopmydata);
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      break;
    default:
      break;
  }

  return ret;
}

static void
get_next_size (GstChopMyData * chopmydata)
{
  int begin;
  int end;

  begin = (chopmydata->min_size + chopmydata->step_size - 1) /
      chopmydata->step_size;
  end = (chopmydata->max_size + chopmydata->step_size) / chopmydata->step_size;

  if (begin >= end) {
    chopmydata->next_size = begin * chopmydata->step_size;
    return;
  }

  chopmydata->next_size =
      g_rand_int_range (chopmydata->rand, begin, end) * chopmydata->step_size;
}

static GstFlowReturn
gst_chop_my_data_process (GstChopMyData * chopmydata, gboolean flush)
{
  GstFlowReturn ret = GST_FLOW_OK;
  GstBuffer *buffer;

  if (chopmydata->next_size == 0) {
    get_next_size (chopmydata);
  }

  while (gst_adapter_available (chopmydata->adapter) >= chopmydata->next_size) {
    buffer =
        gst_adapter_take_buffer (chopmydata->adapter, chopmydata->next_size);

    chopmydata->next_size = 0;

    ret = gst_pad_push (chopmydata->srcpad, buffer);
    if (ret != GST_FLOW_OK) {
      return ret;
    }

    get_next_size (chopmydata);
  }

  if (flush) {
    guint min_size = chopmydata->min_size;

    while (gst_adapter_available (chopmydata->adapter) >= min_size) {
      buffer = gst_adapter_take_buffer (chopmydata->adapter, min_size);
      ret = gst_pad_push (chopmydata->srcpad, buffer);
      if (ret != GST_FLOW_OK)
        break;
    }
    gst_adapter_clear (chopmydata->adapter);
  }

  return ret;
}

static GstFlowReturn
gst_chop_my_data_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
{
  GstChopMyData *chopmydata;
  GstFlowReturn ret;

  chopmydata = GST_CHOP_MY_DATA (parent);

  GST_DEBUG_OBJECT (chopmydata, "chain");

  gst_adapter_push (chopmydata->adapter, buffer);
  ret = gst_chop_my_data_process (chopmydata, FALSE);

  return ret;
}

static gboolean
gst_chop_my_data_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  gboolean res;
  GstChopMyData *chopmydata;

  chopmydata = GST_CHOP_MY_DATA (parent);

  GST_DEBUG_OBJECT (chopmydata, "event");

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_START:
      res = gst_pad_push_event (chopmydata->srcpad, event);
      break;
    case GST_EVENT_FLUSH_STOP:
      gst_adapter_clear (chopmydata->adapter);
      res = gst_pad_push_event (chopmydata->srcpad, event);
      break;
    case GST_EVENT_SEGMENT:
      res = gst_pad_push_event (chopmydata->srcpad, event);
      break;
    case GST_EVENT_EOS:
      gst_chop_my_data_process (chopmydata, TRUE);
      res = gst_pad_push_event (chopmydata->srcpad, event);
      break;
    default:
      res = gst_pad_push_event (chopmydata->srcpad, event);
      break;
  }

  return res;
}

static gboolean
gst_chop_my_data_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  gboolean res;
  GstChopMyData *chopmydata;

  chopmydata = GST_CHOP_MY_DATA (parent);

  GST_DEBUG_OBJECT (chopmydata, "event");

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEEK:
      res = gst_pad_push_event (chopmydata->sinkpad, event);
      break;
    default:
      res = gst_pad_push_event (chopmydata->sinkpad, event);
      break;
  }

  return res;
}
