/* GStreamer
 * Copyright (C) 2014 Wim Taymans <wim.taymans@gmail.com>
 *
 * gstdownloadbuffer.c:
 *
 * 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-downloadbuffer
 *
 * The downloadbuffer element provides on-disk buffering and caching of, typically,
 * a network file. temp-template should be set to a value such as
 * /tmp/gstreamer-XXXXXX and the element will allocate a random free filename and
 * buffer the data in the file.
 *
 * With max-size-bytes and max-size-time you can configure the buffering limits.
 * The downloadbuffer element will try to read-ahead these amounts of data. When
 * the amount of read-ahead data drops below low-percent of the configured max,
 * the element will start emiting BUFFERING messages until high-percent of max is
 * reached again.
 *
 * The downloadbuffer provides push and pull based scheduling on its source pad
 * and will efficiently seek in the upstream element when needed.
 *
 * The temp-location property will be used to notify the application of the
 * allocated filename.
 *
 * When the downloadbuffer has completely downloaded the media, it will
 * post an application message named  <classname>&quot;GstCacheDownloadComplete&quot;</classname>
 * with the following information:
 * <itemizedlist>
 * <listitem>
 *   <para>
 *   G_TYPE_STRING
 *   <classname>&quot;location&quot;</classname>:
 *   the location of the completely downloaded file.
 *   </para>
 * </listitem>
 * </itemizedlist>
 */

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

#include "gstdownloadbuffer.h"

#include <glib/gstdio.h>

#include "gst/gst-i18n-lib.h"
#include "gst/glib-compat-private.h"

#include <string.h>

#ifdef G_OS_WIN32
#include <io.h>                 /* lseek, open, close, read */
#undef lseek
#define lseek _lseeki64
#undef off_t
#define off_t guint64
#else
#include <unistd.h>
#endif

#ifdef __BIONIC__
#include <fcntl.h>
#endif

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

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

GST_DEBUG_CATEGORY_STATIC (downloadbuffer_debug);
#define GST_CAT_DEFAULT (downloadbuffer_debug)

enum
{
  LAST_SIGNAL
};

/* other defines */
#define DEFAULT_BUFFER_SIZE 4096

/* default property values */
#define DEFAULT_MAX_SIZE_BYTES     (2 * 1024 * 1024)    /* 2 MB */
#define DEFAULT_MAX_SIZE_TIME      2 * GST_SECOND       /* 2 seconds */
#define DEFAULT_LOW_PERCENT        10
#define DEFAULT_HIGH_PERCENT       99
#define DEFAULT_TEMP_REMOVE        TRUE

enum
{
  PROP_0,
  PROP_MAX_SIZE_BYTES,
  PROP_MAX_SIZE_TIME,
  PROP_LOW_PERCENT,
  PROP_HIGH_PERCENT,
  PROP_TEMP_TEMPLATE,
  PROP_TEMP_LOCATION,
  PROP_TEMP_REMOVE,
  PROP_LAST
};

#define GST_DOWNLOAD_BUFFER_CLEAR_LEVEL(l) G_STMT_START {         \
  l.bytes = 0;                                          \
  l.time = 0;                                           \
} G_STMT_END

#define STATUS(elem, pad, msg) \
  GST_LOG_OBJECT (elem, "(%s:%s) " msg ": %u of %u " \
                      "bytes, %" G_GUINT64_FORMAT " of %" G_GUINT64_FORMAT \
                      " ns", \
                      GST_DEBUG_PAD_NAME (pad), \
                      elem->cur_level.bytes, \
                      elem->max_level.bytes, \
                      elem->cur_level.time, \
                      elem->max_level.time)

#define GST_DOWNLOAD_BUFFER_MUTEX_LOCK(q) G_STMT_START {                          \
  g_mutex_lock (&q->qlock);                                              \
} G_STMT_END

#define GST_DOWNLOAD_BUFFER_MUTEX_LOCK_CHECK(q,res,label) G_STMT_START {         \
  GST_DOWNLOAD_BUFFER_MUTEX_LOCK (q);                                            \
  if (res != GST_FLOW_OK)                                               \
    goto label;                                                         \
} G_STMT_END

#define GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK(q) G_STMT_START {                        \
  g_mutex_unlock (&q->qlock);                                            \
} G_STMT_END

#define GST_DOWNLOAD_BUFFER_WAIT_ADD_CHECK(q, res, o, label) G_STMT_START {       \
  STATUS (q, q->srcpad, "wait for ADD");                            \
  q->waiting_add = TRUE;                                                \
  q->waiting_offset = o;                                                \
  g_cond_wait (&q->item_add, &q->qlock);                                \
  q->waiting_add = FALSE;                                               \
  if (res != GST_FLOW_OK) {                                             \
    STATUS (q, q->srcpad, "received ADD wakeup");                   \
    goto label;                                                         \
  }                                                                     \
  STATUS (q, q->srcpad, "received ADD");                            \
} G_STMT_END

#define GST_DOWNLOAD_BUFFER_SIGNAL_ADD(q, o) G_STMT_START {                       \
  if (q->waiting_add && q->waiting_offset <= o) {                       \
    STATUS (q, q->sinkpad, "signal ADD");                               \
    g_cond_signal (&q->item_add);                                       \
  }                                                                     \
} G_STMT_END

#define _do_init \
    GST_DEBUG_CATEGORY_INIT (downloadbuffer_debug, "downloadbuffer", 0, \
        "downloadbuffer element");

#define gst_download_buffer_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstDownloadBuffer, gst_download_buffer,
    GST_TYPE_ELEMENT, _do_init);

static GstMessage *update_buffering (GstDownloadBuffer * dlbuf);

static void gst_download_buffer_finalize (GObject * object);

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

static GstFlowReturn gst_download_buffer_chain (GstPad * pad,
    GstObject * parent, GstBuffer * buffer);
static void gst_download_buffer_loop (GstPad * pad);

static gboolean gst_download_buffer_handle_sink_event (GstPad * pad,
    GstObject * parent, GstEvent * event);
static gboolean gst_download_buffer_handle_sink_query (GstPad * pad,
    GstObject * parent, GstQuery * query);

static gboolean gst_download_buffer_handle_src_event (GstPad * pad,
    GstObject * parent, GstEvent * event);
static gboolean gst_download_buffer_handle_src_query (GstPad * pad,
    GstObject * parent, GstQuery * query);
static gboolean gst_download_buffer_handle_query (GstElement * element,
    GstQuery * query);

static GstFlowReturn gst_download_buffer_get_range (GstPad * pad,
    GstObject * parent, guint64 offset, guint length, GstBuffer ** buffer);

static gboolean gst_download_buffer_src_activate_mode (GstPad * pad,
    GstObject * parent, GstPadMode mode, gboolean active);
static gboolean gst_download_buffer_sink_activate_mode (GstPad * pad,
    GstObject * parent, GstPadMode mode, gboolean active);
static GstStateChangeReturn gst_download_buffer_change_state (GstElement *
    element, GstStateChange transition);

/* static guint gst_download_buffer_signals[LAST_SIGNAL] = { 0 }; */

static void
gst_download_buffer_class_init (GstDownloadBufferClass * klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);

  gobject_class->set_property = gst_download_buffer_set_property;
  gobject_class->get_property = gst_download_buffer_get_property;

  /* properties */
  g_object_class_install_property (gobject_class, PROP_MAX_SIZE_BYTES,
      g_param_spec_uint ("max-size-bytes", "Max. size (kB)",
          "Max. amount of data to buffer (bytes, 0=disable)",
          0, G_MAXUINT, DEFAULT_MAX_SIZE_BYTES,
          G_PARAM_READWRITE | GST_PARAM_MUTABLE_PLAYING |
          G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_MAX_SIZE_TIME,
      g_param_spec_uint64 ("max-size-time", "Max. size (ns)",
          "Max. amount of data to buffer (in ns, 0=disable)", 0, G_MAXUINT64,
          DEFAULT_MAX_SIZE_TIME, G_PARAM_READWRITE | GST_PARAM_MUTABLE_PLAYING |
          G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_LOW_PERCENT,
      g_param_spec_int ("low-percent", "Low percent",
          "Low threshold for buffering to start. Only used if use-buffering is True",
          0, 100, DEFAULT_LOW_PERCENT,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_HIGH_PERCENT,
      g_param_spec_int ("high-percent", "High percent",
          "High threshold for buffering to finish. Only used if use-buffering is True",
          0, 100, DEFAULT_HIGH_PERCENT,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_TEMP_TEMPLATE,
      g_param_spec_string ("temp-template", "Temporary File Template",
          "File template to store temporary files in, should contain directory "
          "and XXXXXX. (NULL == disabled)",
          NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_TEMP_LOCATION,
      g_param_spec_string ("temp-location", "Temporary File Location",
          "Location to store temporary files in (Only read this property, "
          "use temp-template to configure the name template)",
          NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));

  /**
   * GstDownloadBuffer:temp-remove
   *
   * When temp-template is set, remove the temporary file when going to READY.
   */
  g_object_class_install_property (gobject_class, PROP_TEMP_REMOVE,
      g_param_spec_boolean ("temp-remove", "Remove the Temporary File",
          "Remove the temp-location after use",
          DEFAULT_TEMP_REMOVE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /* set several parent class virtual functions */
  gobject_class->finalize = gst_download_buffer_finalize;

  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&srctemplate));
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&sinktemplate));

  gst_element_class_set_static_metadata (gstelement_class, "DownloadBuffer",
      "Generic", "Download Buffer element",
      "Wim Taymans <wim.taymans@gmail.com>");

  gstelement_class->change_state =
      GST_DEBUG_FUNCPTR (gst_download_buffer_change_state);
  gstelement_class->query =
      GST_DEBUG_FUNCPTR (gst_download_buffer_handle_query);
}

static void
gst_download_buffer_init (GstDownloadBuffer * dlbuf)
{
  dlbuf->sinkpad = gst_pad_new_from_static_template (&sinktemplate, "sink");

  gst_pad_set_chain_function (dlbuf->sinkpad,
      GST_DEBUG_FUNCPTR (gst_download_buffer_chain));
  gst_pad_set_activatemode_function (dlbuf->sinkpad,
      GST_DEBUG_FUNCPTR (gst_download_buffer_sink_activate_mode));
  gst_pad_set_event_function (dlbuf->sinkpad,
      GST_DEBUG_FUNCPTR (gst_download_buffer_handle_sink_event));
  gst_pad_set_query_function (dlbuf->sinkpad,
      GST_DEBUG_FUNCPTR (gst_download_buffer_handle_sink_query));
  GST_PAD_SET_PROXY_CAPS (dlbuf->sinkpad);
  gst_element_add_pad (GST_ELEMENT (dlbuf), dlbuf->sinkpad);

  dlbuf->srcpad = gst_pad_new_from_static_template (&srctemplate, "src");

  gst_pad_set_activatemode_function (dlbuf->srcpad,
      GST_DEBUG_FUNCPTR (gst_download_buffer_src_activate_mode));
  gst_pad_set_getrange_function (dlbuf->srcpad,
      GST_DEBUG_FUNCPTR (gst_download_buffer_get_range));
  gst_pad_set_event_function (dlbuf->srcpad,
      GST_DEBUG_FUNCPTR (gst_download_buffer_handle_src_event));
  gst_pad_set_query_function (dlbuf->srcpad,
      GST_DEBUG_FUNCPTR (gst_download_buffer_handle_src_query));
  GST_PAD_SET_PROXY_CAPS (dlbuf->srcpad);
  gst_element_add_pad (GST_ELEMENT (dlbuf), dlbuf->srcpad);

  /* levels */
  GST_DOWNLOAD_BUFFER_CLEAR_LEVEL (dlbuf->cur_level);
  dlbuf->max_level.bytes = DEFAULT_MAX_SIZE_BYTES;
  dlbuf->max_level.time = DEFAULT_MAX_SIZE_TIME;
  dlbuf->low_percent = DEFAULT_LOW_PERCENT;
  dlbuf->high_percent = DEFAULT_HIGH_PERCENT;

  dlbuf->srcresult = GST_FLOW_FLUSHING;
  dlbuf->sinkresult = GST_FLOW_FLUSHING;
  dlbuf->in_timer = g_timer_new ();
  dlbuf->out_timer = g_timer_new ();

  g_mutex_init (&dlbuf->qlock);
  dlbuf->waiting_add = FALSE;
  g_cond_init (&dlbuf->item_add);

  /* tempfile related */
  dlbuf->temp_template = NULL;
  dlbuf->temp_location = NULL;
  dlbuf->temp_remove = DEFAULT_TEMP_REMOVE;
}

/* called only once, as opposed to dispose */
static void
gst_download_buffer_finalize (GObject * object)
{
  GstDownloadBuffer *dlbuf = GST_DOWNLOAD_BUFFER (object);

  g_mutex_clear (&dlbuf->qlock);
  g_cond_clear (&dlbuf->item_add);
  g_timer_destroy (dlbuf->in_timer);
  g_timer_destroy (dlbuf->out_timer);

  /* temp_file path cleanup  */
  g_free (dlbuf->temp_template);
  g_free (dlbuf->temp_location);

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

static void
reset_positions (GstDownloadBuffer * dlbuf)
{
  dlbuf->write_pos = 0;
  dlbuf->read_pos = 0;
  dlbuf->filling = TRUE;
  dlbuf->buffering_percent = 0;
  dlbuf->is_buffering = TRUE;
  dlbuf->seeking = FALSE;
  GST_DOWNLOAD_BUFFER_CLEAR_LEVEL (dlbuf->cur_level);
}

static void
reset_rate_timer (GstDownloadBuffer * dlbuf)
{
  dlbuf->bytes_in = 0;
  dlbuf->bytes_out = 0;
  dlbuf->byte_in_rate = 0.0;
  dlbuf->byte_in_period = 0;
  dlbuf->byte_out_rate = 0.0;
  dlbuf->last_in_elapsed = 0.0;
  dlbuf->last_out_elapsed = 0.0;
  dlbuf->in_timer_started = FALSE;
  dlbuf->out_timer_started = FALSE;
}

/* the interval in seconds to recalculate the rate */
#define RATE_INTERVAL    0.2
/* Tuning for rate estimation. We use a large window for the input rate because
 * it should be stable when connected to a network. The output rate is less
 * stable (the elements preroll, queues behind a demuxer fill, ...) and should
 * therefore adapt more quickly.
 * However, initial input rate may be subject to a burst, and should therefore
 * initially also adapt more quickly to changes, and only later on give higher
 * weight to previous values. */
#define AVG_IN(avg,val,w1,w2)  ((avg) * (w1) + (val) * (w2)) / ((w1) + (w2))
#define AVG_OUT(avg,val) ((avg) * 3.0 + (val)) / 4.0

static void
update_levels (GstDownloadBuffer * dlbuf, guint bytes)
{
  dlbuf->cur_level.bytes = bytes;

  if (dlbuf->byte_in_rate > 0.0) {
    dlbuf->cur_level.time =
        dlbuf->cur_level.bytes / dlbuf->byte_in_rate * GST_SECOND;
  }

  GST_DEBUG ("levels: bytes %u/%u, time %" GST_TIME_FORMAT "/%" GST_TIME_FORMAT,
      dlbuf->cur_level.bytes, dlbuf->max_level.bytes,
      GST_TIME_ARGS (dlbuf->cur_level.time),
      GST_TIME_ARGS (dlbuf->max_level.time));
}

static void
update_in_rates (GstDownloadBuffer * dlbuf)
{
  gdouble elapsed, period;
  gdouble byte_in_rate;

  if (!dlbuf->in_timer_started) {
    dlbuf->in_timer_started = TRUE;
    g_timer_start (dlbuf->in_timer);
    return;
  }

  elapsed = g_timer_elapsed (dlbuf->in_timer, NULL);

  /* recalc after each interval. */
  if (dlbuf->last_in_elapsed + RATE_INTERVAL < elapsed) {
    period = elapsed - dlbuf->last_in_elapsed;

    GST_DEBUG_OBJECT (dlbuf,
        "rates: period %f, in %" G_GUINT64_FORMAT ", global period %f",
        period, dlbuf->bytes_in, dlbuf->byte_in_period);

    byte_in_rate = dlbuf->bytes_in / period;

    if (dlbuf->byte_in_rate == 0.0)
      dlbuf->byte_in_rate = byte_in_rate;
    else
      dlbuf->byte_in_rate = AVG_IN (dlbuf->byte_in_rate, byte_in_rate,
          (double) dlbuf->byte_in_period, period);

    /* another data point, cap at 16 for long time running average */
    if (dlbuf->byte_in_period < 16 * RATE_INTERVAL)
      dlbuf->byte_in_period += period;

    /* reset the values to calculate rate over the next interval */
    dlbuf->last_in_elapsed = elapsed;
    dlbuf->bytes_in = 0;
    GST_DEBUG_OBJECT (dlbuf, "rates: in %f", dlbuf->byte_in_rate);
  }
}

static void
update_out_rates (GstDownloadBuffer * dlbuf)
{
  gdouble elapsed, period;
  gdouble byte_out_rate;

  if (!dlbuf->out_timer_started) {
    dlbuf->out_timer_started = TRUE;
    g_timer_start (dlbuf->out_timer);
    return;
  }

  elapsed = g_timer_elapsed (dlbuf->out_timer, NULL);

  /* recalc after each interval. */
  if (dlbuf->last_out_elapsed + RATE_INTERVAL < elapsed) {
    period = elapsed - dlbuf->last_out_elapsed;

    GST_DEBUG_OBJECT (dlbuf,
        "rates: period %f, out %" G_GUINT64_FORMAT, period, dlbuf->bytes_out);

    byte_out_rate = dlbuf->bytes_out / period;

    if (dlbuf->byte_out_rate == 0.0)
      dlbuf->byte_out_rate = byte_out_rate;
    else
      dlbuf->byte_out_rate = AVG_OUT (dlbuf->byte_out_rate, byte_out_rate);

    /* reset the values to calculate rate over the next interval */
    dlbuf->last_out_elapsed = elapsed;
    dlbuf->bytes_out = 0;
    GST_DEBUG_OBJECT (dlbuf, "rates: out %f", dlbuf->byte_out_rate);
  }
}

static gboolean
get_buffering_percent (GstDownloadBuffer * dlbuf, gboolean * is_buffering,
    gint * percent)
{
  gint perc;

  if (dlbuf->high_percent <= 0) {
    if (percent)
      *percent = 100;
    if (is_buffering)
      *is_buffering = FALSE;
    return FALSE;
  }

  /* Ensure the variables used to calculate buffering state are up-to-date. */
  update_in_rates (dlbuf);
  update_out_rates (dlbuf);

  /* figure out the percent we are filled, we take the max of all formats. */
  if (dlbuf->max_level.bytes > 0) {
    if (dlbuf->cur_level.bytes >= dlbuf->max_level.bytes)
      perc = 100;
    else
      perc = dlbuf->cur_level.bytes * 100 / dlbuf->max_level.bytes;
  } else
    perc = 0;

  if (dlbuf->max_level.time > 0) {
    if (dlbuf->cur_level.time >= dlbuf->max_level.time)
      perc = 100;
    else
      perc = MAX (perc, dlbuf->cur_level.time * 100 / dlbuf->max_level.time);
  } else
    perc = MAX (0, perc);

  if (is_buffering)
    *is_buffering = dlbuf->is_buffering;

  /* scale to high percent so that it becomes the 100% mark */
  perc = perc * 100 / dlbuf->high_percent;
  /* clip */
  if (perc > 100)
    perc = 100;

  if (percent)
    *percent = perc;

  GST_DEBUG_OBJECT (dlbuf, "buffering %d, percent %d", dlbuf->is_buffering,
      perc);

  return TRUE;
}

static void
get_buffering_stats (GstDownloadBuffer * dlbuf, gint percent,
    GstBufferingMode * mode, gint * avg_in, gint * avg_out,
    gint64 * buffering_left)
{
  if (mode)
    *mode = GST_BUFFERING_DOWNLOAD;

  if (avg_in)
    *avg_in = dlbuf->byte_in_rate;
  if (avg_out)
    *avg_out = dlbuf->byte_out_rate;

  if (buffering_left) {
    guint64 max, cur;

    *buffering_left = (percent == 100 ? 0 : -1);

    max = dlbuf->max_level.time;
    cur = dlbuf->cur_level.time;

    if (percent != 100 && max > cur)
      *buffering_left = (max - cur) / 1000000;
  }
}

static GstMessage *
update_buffering (GstDownloadBuffer * dlbuf)
{
  gint percent;
  gboolean post = FALSE;
  GstMessage *message = NULL;

  if (!get_buffering_percent (dlbuf, NULL, &percent))
    return NULL;

  if (dlbuf->is_buffering) {
    post = TRUE;
    /* if we were buffering see if we reached the high watermark */
    if (percent >= dlbuf->high_percent)
      dlbuf->is_buffering = FALSE;
  } else {
    /* we were not buffering, check if we need to start buffering if we drop
     * below the low threshold */
    if (percent < dlbuf->low_percent) {
      dlbuf->is_buffering = TRUE;
      post = TRUE;
    }
  }

  if (post) {
    if (percent == dlbuf->buffering_percent)
      post = FALSE;
    else
      dlbuf->buffering_percent = percent;
  }

  if (post) {
    GstBufferingMode mode;
    gint avg_in, avg_out;
    gint64 buffering_left;

    get_buffering_stats (dlbuf, percent, &mode, &avg_in, &avg_out,
        &buffering_left);

    message = gst_message_new_buffering (GST_OBJECT_CAST (dlbuf),
        (gint) percent);
    gst_message_set_buffering_stats (message, mode,
        avg_in, avg_out, buffering_left);
  }

  return message;
}

static gboolean
perform_seek_to_offset (GstDownloadBuffer * dlbuf, guint64 offset)
{
  GstEvent *event;
  gboolean res;

  if (dlbuf->seeking)
    return TRUE;

  /* until we receive the FLUSH_STOP from this seek, we skip data */
  dlbuf->seeking = TRUE;
  dlbuf->write_pos = offset;
  dlbuf->filling = FALSE;
  GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK (dlbuf);

  GST_DEBUG_OBJECT (dlbuf, "Seeking to %" G_GUINT64_FORMAT, offset);

  event =
      gst_event_new_seek (1.0, GST_FORMAT_BYTES,
      GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
      GST_SEEK_TYPE_NONE, -1);

  res = gst_pad_push_event (dlbuf->sinkpad, event);
  GST_DOWNLOAD_BUFFER_MUTEX_LOCK (dlbuf);

  return res;
}

/* get the threshold for when we decide to seek rather than wait */
static guint64
get_seek_threshold (GstDownloadBuffer * dlbuf)
{
  guint64 threshold;

  /* FIXME, find a good threshold based on the incoming rate. */
  threshold = 1024 * 512;

  return threshold;
}

/* called with DOWNLOAD_BUFFER_MUTEX */
static void
gst_download_buffer_update_upstream_size (GstDownloadBuffer * dlbuf)
{
  gint64 upstream_size = 0;

  if (gst_pad_peer_query_duration (dlbuf->sinkpad, GST_FORMAT_BYTES,
          &upstream_size)) {
    GST_INFO_OBJECT (dlbuf, "upstream size: %" G_GINT64_FORMAT, upstream_size);
    dlbuf->upstream_size = upstream_size;
  }
}

/* called with DOWNLOAD_BUFFER_MUTEX */
static GstFlowReturn
gst_download_buffer_wait_for_data (GstDownloadBuffer * dlbuf, guint64 offset,
    guint length)
{
  gsize start, stop;
  guint64 wanted;
  gboolean started;

  GST_DEBUG_OBJECT (dlbuf, "wait for %" G_GUINT64_FORMAT ", length %u",
      offset, length);

  wanted = offset + length;

  /* pause the timer while we wait. The fact that we are waiting does not mean
   * the byterate on the output pad is lower */
  if ((started = dlbuf->out_timer_started))
    g_timer_stop (dlbuf->out_timer);

  /* check range before us */
  if (gst_sparse_file_get_range_before (dlbuf->file, offset, &start, &stop)) {
    GST_DEBUG_OBJECT (dlbuf,
        "range before %" G_GSIZE_FORMAT " - %" G_GSIZE_FORMAT, start, stop);
    if (start <= offset && offset < stop) {
      GST_DEBUG_OBJECT (dlbuf, "we have the offset");
      /* we have the range, continue it */
      offset = stop;
    } else {
      guint64 threshold, dist;

      /* there is a range before us, check how far away it is */
      threshold = get_seek_threshold (dlbuf);
      dist = offset - stop;

      if (dist <= threshold) {
        GST_DEBUG_OBJECT (dlbuf, "not too far");
        /* not far away, continue it */
        offset = stop;
      }
    }
  }

  if (dlbuf->write_pos != offset)
    perform_seek_to_offset (dlbuf, offset);

  dlbuf->filling = TRUE;
  if (dlbuf->write_pos > dlbuf->read_pos)
    update_levels (dlbuf, dlbuf->write_pos - dlbuf->read_pos);
  else
    update_levels (dlbuf, 0);

  /* now wait for more data */
  GST_DEBUG_OBJECT (dlbuf, "waiting for more data");
  GST_DOWNLOAD_BUFFER_WAIT_ADD_CHECK (dlbuf, dlbuf->srcresult, wanted,
      out_flushing);
  GST_DEBUG_OBJECT (dlbuf, "got more data");

  /* and continue if we were running before */
  if (started)
    g_timer_continue (dlbuf->out_timer);

  return GST_FLOW_OK;

out_flushing:
  {
    GST_DEBUG_OBJECT (dlbuf, "we are flushing");
    return GST_FLOW_FLUSHING;
  }
}

/* called with DOWNLOAD_BUFFER_MUTEX */
static gboolean
check_upstream_size (GstDownloadBuffer * dlbuf, gsize offset, guint * length)
{
  gsize stop = offset + *length;
  /* catch any reads beyond the size of the file here to make sure cache
   * doesn't send seek events beyond the size of the file upstream, since
   * that would confuse elements such as souphttpsrc and/or http servers.
   * Demuxers often just loop until EOS at the end of the file to figure out
   * when they've read all the end-headers or index chunks. */
  if (G_UNLIKELY (dlbuf->upstream_size == -1 || stop >= dlbuf->upstream_size)) {
    gst_download_buffer_update_upstream_size (dlbuf);
  }

  if (dlbuf->upstream_size != -1) {
    if (offset >= dlbuf->upstream_size)
      return FALSE;

    if (G_UNLIKELY (stop > dlbuf->upstream_size)) {
      *length = dlbuf->upstream_size - offset;
      GST_DEBUG_OBJECT (dlbuf, "adjusting length downto %u", *length);
    }
  }
  return TRUE;
}

/* called with DOWNLOAD_BUFFER_MUTEX */
static GstFlowReturn
gst_download_buffer_read_buffer (GstDownloadBuffer * dlbuf, guint64 offset,
    guint length, GstBuffer ** buffer)
{
  GstBuffer *buf;
  GstMapInfo info;
  GstFlowReturn ret = GST_FLOW_OK;
  gsize res, remaining;
  GError *error = NULL;

  length = (length == -1) ? DEFAULT_BUFFER_SIZE : length;
  offset = (offset == -1) ? dlbuf->read_pos : offset;

  if (!check_upstream_size (dlbuf, offset, &length))
    goto hit_eos;

  /* allocate the output buffer of the requested size */
  if (*buffer == NULL)
    buf = gst_buffer_new_allocate (NULL, length, NULL);
  else
    buf = *buffer;

  gst_buffer_map (buf, &info, GST_MAP_WRITE);

  GST_DEBUG_OBJECT (dlbuf, "Reading %u bytes from %" G_GUINT64_FORMAT, length,
      offset);

  dlbuf->read_pos = offset;

  do {
    res =
        gst_sparse_file_read (dlbuf->file, offset, info.data, length,
        &remaining, &error);
    if (G_UNLIKELY (res == 0)) {
      switch (error->code) {
        case GST_SPARSE_FILE_IO_ERROR_WOULD_BLOCK:
          /* we don't have the requested data in the file, decide what to
           * do next. */
          ret = gst_download_buffer_wait_for_data (dlbuf, offset, length);
          if (ret != GST_FLOW_OK)
            goto out_flushing;
          break;
        default:
          goto read_error;
      }
      g_clear_error (&error);
    }
  } while (res == 0);

  gst_buffer_unmap (buf, &info);
  gst_buffer_resize (buf, 0, res);

  dlbuf->bytes_out += res;
  dlbuf->read_pos += res;

  GST_DEBUG_OBJECT (dlbuf,
      "Read %" G_GSIZE_FORMAT " bytes, remaining %" G_GSIZE_FORMAT, res,
      remaining);

  if (dlbuf->read_pos + remaining == dlbuf->upstream_size)
    update_levels (dlbuf, dlbuf->max_level.bytes);
  else
    update_levels (dlbuf, remaining);

  GST_BUFFER_OFFSET (buf) = offset;
  GST_BUFFER_OFFSET_END (buf) = offset + res;

  *buffer = buf;

  return ret;

  /* ERRORS */
hit_eos:
  {
    GST_DEBUG_OBJECT (dlbuf, "EOS hit");
    return GST_FLOW_EOS;
  }
out_flushing:
  {
    GST_DEBUG_OBJECT (dlbuf, "we are flushing");
    g_clear_error (&error);
    gst_buffer_unmap (buf, &info);
    if (*buffer == NULL)
      gst_buffer_unref (buf);
    return GST_FLOW_FLUSHING;
  }
read_error:
  {
    GST_DEBUG_OBJECT (dlbuf, "we have a read error: %s", error->message);
    g_clear_error (&error);
    gst_buffer_unmap (buf, &info);
    if (*buffer == NULL)
      gst_buffer_unref (buf);
    return ret;
  }
}

/* must be called with MUTEX_LOCK. Will briefly release the lock when notifying
 * the temp filename. */
static gboolean
gst_download_buffer_open_temp_location_file (GstDownloadBuffer * dlbuf)
{
  gint fd = -1;
  gchar *name = NULL;

  if (dlbuf->file)
    goto already_opened;

  GST_DEBUG_OBJECT (dlbuf, "opening temp file %s", dlbuf->temp_template);

  /* If temp_template was set, allocate a filename and open that filen */

  /* nothing to do */
  if (dlbuf->temp_template == NULL)
    goto no_directory;

  /* make copy of the template, we don't want to change this */
  name = g_strdup (dlbuf->temp_template);
#ifdef __BIONIC__
  fd = g_mkstemp_full (name, O_RDWR | O_LARGEFILE, S_IRUSR | S_IWUSR);
#else
  fd = g_mkstemp (name);
#endif
  if (fd == -1)
    goto mkstemp_failed;

  /* open the file for update/writing */
  dlbuf->file = gst_sparse_file_new ();
  /* error creating file */
  if (!gst_sparse_file_set_fd (dlbuf->file, fd))
    goto open_failed;

  g_free (dlbuf->temp_location);
  dlbuf->temp_location = name;
  dlbuf->temp_fd = fd;
  reset_positions (dlbuf);

  GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK (dlbuf);

  /* we can't emit the notify with the lock */
  g_object_notify (G_OBJECT (dlbuf), "temp-location");

  GST_DOWNLOAD_BUFFER_MUTEX_LOCK (dlbuf);

  GST_DEBUG_OBJECT (dlbuf, "opened temp file %s", dlbuf->temp_template);

  return TRUE;

  /* ERRORS */
already_opened:
  {
    GST_DEBUG_OBJECT (dlbuf, "temp file was already open");
    return TRUE;
  }
no_directory:
  {
    GST_ELEMENT_ERROR (dlbuf, RESOURCE, NOT_FOUND,
        (_("No Temp directory specified.")), (NULL));
    return FALSE;
  }
mkstemp_failed:
  {
    GST_ELEMENT_ERROR (dlbuf, RESOURCE, OPEN_READ,
        (_("Could not create temp file \"%s\"."), dlbuf->temp_template),
        GST_ERROR_SYSTEM);
    g_free (name);
    return FALSE;
  }
open_failed:
  {
    GST_ELEMENT_ERROR (dlbuf, RESOURCE, OPEN_READ,
        (_("Could not open file \"%s\" for reading."), name), GST_ERROR_SYSTEM);
    g_free (name);
    if (fd != -1)
      close (fd);
    return FALSE;
  }
}

static void
gst_download_buffer_close_temp_location_file (GstDownloadBuffer * dlbuf)
{
  /* nothing to do */
  if (dlbuf->file == NULL)
    return;

  GST_DEBUG_OBJECT (dlbuf, "closing sparse file");

  if (dlbuf->temp_remove) {
    if (remove (dlbuf->temp_location) < 0) {
      GST_WARNING_OBJECT (dlbuf, "Failed to remove temporary file %s: %s",
          dlbuf->temp_location, g_strerror (errno));
    }
  }
  gst_sparse_file_free (dlbuf->file);
  close (dlbuf->temp_fd);
  dlbuf->file = NULL;
}

static void
gst_download_buffer_flush_temp_file (GstDownloadBuffer * dlbuf)
{
  if (dlbuf->file == NULL)
    return;

  GST_DEBUG_OBJECT (dlbuf, "flushing temp file");

  gst_sparse_file_clear (dlbuf->file);
}

static void
gst_download_buffer_locked_flush (GstDownloadBuffer * dlbuf, gboolean full,
    gboolean clear_temp)
{
  if (clear_temp)
    gst_download_buffer_flush_temp_file (dlbuf);
  reset_positions (dlbuf);
  gst_event_replace (&dlbuf->stream_start_event, NULL);
  gst_event_replace (&dlbuf->segment_event, NULL);
}

static gboolean
gst_download_buffer_handle_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event)
{
  gboolean ret = TRUE;
  GstDownloadBuffer *dlbuf;

  dlbuf = GST_DOWNLOAD_BUFFER (parent);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_START:
    {
      GST_LOG_OBJECT (dlbuf, "received flush start event");
      if (GST_PAD_MODE (dlbuf->srcpad) == GST_PAD_MODE_PUSH) {
        /* forward event */
        ret = gst_pad_push_event (dlbuf->srcpad, event);

        /* now unblock the chain function */
        GST_DOWNLOAD_BUFFER_MUTEX_LOCK (dlbuf);
        dlbuf->srcresult = GST_FLOW_FLUSHING;
        dlbuf->sinkresult = GST_FLOW_FLUSHING;
        /* unblock the loop and chain functions */
        GST_DOWNLOAD_BUFFER_SIGNAL_ADD (dlbuf, -1);
        GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK (dlbuf);

        /* make sure it pauses, this should happen since we sent
         * flush_start downstream. */
        gst_pad_pause_task (dlbuf->srcpad);
        GST_LOG_OBJECT (dlbuf, "loop stopped");
      } else {
        GST_DOWNLOAD_BUFFER_MUTEX_LOCK (dlbuf);
        /* flush the sink pad */
        dlbuf->sinkresult = GST_FLOW_FLUSHING;
        GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK (dlbuf);

        gst_event_unref (event);
      }
      break;
    }
    case GST_EVENT_FLUSH_STOP:
    {
      GST_LOG_OBJECT (dlbuf, "received flush stop event");

      if (GST_PAD_MODE (dlbuf->srcpad) == GST_PAD_MODE_PUSH) {
        /* forward event */
        ret = gst_pad_push_event (dlbuf->srcpad, event);

        GST_DOWNLOAD_BUFFER_MUTEX_LOCK (dlbuf);
        gst_download_buffer_locked_flush (dlbuf, FALSE, TRUE);
        dlbuf->srcresult = GST_FLOW_OK;
        dlbuf->sinkresult = GST_FLOW_OK;
        dlbuf->unexpected = FALSE;
        dlbuf->seeking = FALSE;
        /* reset rate counters */
        reset_rate_timer (dlbuf);
        gst_pad_start_task (dlbuf->srcpad,
            (GstTaskFunction) gst_download_buffer_loop, dlbuf->srcpad, NULL);
        GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK (dlbuf);
      } else {
        GST_DOWNLOAD_BUFFER_MUTEX_LOCK (dlbuf);
        dlbuf->unexpected = FALSE;
        dlbuf->sinkresult = GST_FLOW_OK;
        dlbuf->seeking = FALSE;
        GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK (dlbuf);

        gst_event_unref (event);
      }
      break;
    }
    default:
      if (GST_EVENT_IS_SERIALIZED (event)) {
        GstMessage *msg = NULL;

        /* serialized events go in the buffer */
        GST_DOWNLOAD_BUFFER_MUTEX_LOCK_CHECK (dlbuf, dlbuf->sinkresult,
            out_flushing);
        switch (GST_EVENT_TYPE (event)) {
          case GST_EVENT_EOS:
            GST_DEBUG_OBJECT (dlbuf, "we have EOS");
            /* Zero the thresholds, this makes sure the dlbuf is completely
             * filled and we can read all data from the dlbuf. */
            /* update the buffering status */
            update_levels (dlbuf, dlbuf->max_level.bytes);
            /* update the buffering */
            msg = update_buffering (dlbuf);
            /* wakeup the waiter and let it recheck */
            GST_DOWNLOAD_BUFFER_SIGNAL_ADD (dlbuf, -1);
            break;
          case GST_EVENT_SEGMENT:
            gst_event_replace (&dlbuf->segment_event, event);
            /* a new segment allows us to accept more buffers if we got EOS
             * from downstream */
            dlbuf->unexpected = FALSE;
            break;
          case GST_EVENT_STREAM_START:
            gst_event_replace (&dlbuf->stream_start_event, event);
            break;
          default:
            break;
        }
        gst_event_unref (event);
        GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK (dlbuf);
        if (msg != NULL)
          gst_element_post_message (GST_ELEMENT_CAST (dlbuf), msg);
      } else {
        /* non-serialized events are passed upstream. */
        ret = gst_pad_push_event (dlbuf->srcpad, event);
      }
      break;
  }
  return ret;

  /* ERRORS */
out_flushing:
  {
    GST_DEBUG_OBJECT (dlbuf, "refusing event, we are flushing");
    GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK (dlbuf);
    gst_event_unref (event);
    return FALSE;
  }
}

static gboolean
gst_download_buffer_handle_sink_query (GstPad * pad, GstObject * parent,
    GstQuery * query)
{
  GstDownloadBuffer *dlbuf;
  gboolean res;

  dlbuf = GST_DOWNLOAD_BUFFER (parent);

  switch (GST_QUERY_TYPE (query)) {
    default:
      if (GST_QUERY_IS_SERIALIZED (query)) {
        GST_LOG_OBJECT (dlbuf, "received query %p", query);
        GST_DEBUG_OBJECT (dlbuf, "refusing query, we are not using the dlbuf");
        res = FALSE;
      } else {
        res = gst_pad_query_default (pad, parent, query);
      }
      break;
  }
  return res;
}

static GstFlowReturn
gst_download_buffer_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
{
  GstDownloadBuffer *dlbuf;
  GstMapInfo info;
  guint64 offset;
  gsize res, available;
  GError *error = NULL;
  GstMessage *msg = NULL;

  dlbuf = GST_DOWNLOAD_BUFFER (parent);

  GST_LOG_OBJECT (dlbuf, "received buffer %p of "
      "size %" G_GSIZE_FORMAT ", time %" GST_TIME_FORMAT ", duration %"
      GST_TIME_FORMAT, buffer, gst_buffer_get_size (buffer),
      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)),
      GST_TIME_ARGS (GST_BUFFER_DURATION (buffer)));

  /* we have to lock the dlbuf since we span threads */
  GST_DOWNLOAD_BUFFER_MUTEX_LOCK_CHECK (dlbuf, dlbuf->sinkresult, out_flushing);
  /* when we received unexpected from downstream, refuse more buffers */
  if (dlbuf->unexpected)
    goto out_eos;

  /* while we didn't receive the newsegment, we're seeking and we skip data */
  if (dlbuf->seeking)
    goto out_seeking;

  /* put buffer in dlbuf now */
  offset = dlbuf->write_pos;

  /* sanity check */
  if (GST_BUFFER_OFFSET_IS_VALID (buffer) &&
      GST_BUFFER_OFFSET (buffer) != offset) {
    GST_WARNING_OBJECT (dlbuf, "buffer offset does not match current writing "
        "position! %" G_GINT64_FORMAT " != %" G_GINT64_FORMAT,
        GST_BUFFER_OFFSET (buffer), offset);
  }

  gst_buffer_map (buffer, &info, GST_MAP_READ);

  GST_DEBUG_OBJECT (dlbuf, "Writing %" G_GSIZE_FORMAT " bytes to %"
      G_GUINT64_FORMAT, info.size, offset);

  res =
      gst_sparse_file_write (dlbuf->file, offset, info.data, info.size,
      &available, &error);
  if (res == 0)
    goto write_error;

  gst_buffer_unmap (buffer, &info);
  gst_buffer_unref (buffer);

  dlbuf->write_pos = offset + info.size;
  dlbuf->bytes_in += info.size;

  GST_DOWNLOAD_BUFFER_SIGNAL_ADD (dlbuf, dlbuf->write_pos + available);

  /* we hit the end, see what to do */
  if (dlbuf->write_pos + available == dlbuf->upstream_size) {
    gsize start, stop;

    /* we have everything up to the end, find a region to fill */
    if (gst_sparse_file_get_range_after (dlbuf->file, 0, &start, &stop)) {
      if (stop < dlbuf->upstream_size) {
        /* a hole to fill, seek to its end */
        perform_seek_to_offset (dlbuf, stop);
      } else {
        /* we filled all the holes, we are done */
        goto completed;
      }
    }
  } else {
    /* see if we need to skip this region or just read it again. The idea
     * is that when the region is not big, we want to avoid a seek and just
     * let it reread */
    guint64 threshold = get_seek_threshold (dlbuf);

    if (available > threshold) {
      /* further than threshold, it's better to skip than to reread */
      perform_seek_to_offset (dlbuf, dlbuf->write_pos + available);
    }
  }
  if (dlbuf->filling) {
    if (dlbuf->write_pos > dlbuf->read_pos)
      update_levels (dlbuf, dlbuf->write_pos - dlbuf->read_pos);
    else
      update_levels (dlbuf, 0);
  }

  /* update the buffering */
  msg = update_buffering (dlbuf);

  GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK (dlbuf);

  if (msg != NULL)
    gst_element_post_message (GST_ELEMENT_CAST (dlbuf), msg);

  return GST_FLOW_OK;

  /* ERRORS */
out_flushing:
  {
    GstFlowReturn ret = dlbuf->sinkresult;
    GST_LOG_OBJECT (dlbuf,
        "exit because task paused, reason: %s", gst_flow_get_name (ret));
    GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK (dlbuf);
    gst_buffer_unref (buffer);
    return ret;
  }
out_eos:
  {
    GST_LOG_OBJECT (dlbuf, "exit because we received EOS");
    GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK (dlbuf);
    gst_buffer_unref (buffer);
    return GST_FLOW_EOS;
  }
out_seeking:
  {
    GST_LOG_OBJECT (dlbuf, "exit because we are seeking");
    GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK (dlbuf);
    gst_buffer_unref (buffer);
    return GST_FLOW_OK;
  }
write_error:
  {
    gst_buffer_unmap (buffer, &info);
    gst_buffer_unref (buffer);
    GST_ELEMENT_ERROR (dlbuf, RESOURCE, WRITE,
        (_("Error while writing to download file.")), ("%s", error->message));
    g_clear_error (&error);
    return GST_FLOW_ERROR;
  }
completed:
  {
    GST_LOG_OBJECT (dlbuf, "we completed the download");
    dlbuf->write_pos = dlbuf->upstream_size;
    dlbuf->filling = FALSE;
    update_levels (dlbuf, dlbuf->max_level.bytes);
    msg = update_buffering (dlbuf);

    gst_element_post_message (GST_ELEMENT_CAST (dlbuf),
        gst_message_new_element (GST_OBJECT_CAST (dlbuf),
            gst_structure_new ("GstCacheDownloadComplete",
                "location", G_TYPE_STRING, dlbuf->temp_location, NULL)));

    GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK (dlbuf);

    if (msg != NULL)
      gst_element_post_message (GST_ELEMENT_CAST (dlbuf), msg);

    return GST_FLOW_EOS;
  }
}

/* called repeatedly with @pad as the source pad. This function should push out
 * data to the peer element. */
static void
gst_download_buffer_loop (GstPad * pad)
{
  GstDownloadBuffer *dlbuf;
  GstFlowReturn ret;
  GstBuffer *buffer = NULL;
  GstMessage *msg = NULL;

  dlbuf = GST_DOWNLOAD_BUFFER (GST_PAD_PARENT (pad));

  /* have to lock for thread-safety */
  GST_DOWNLOAD_BUFFER_MUTEX_LOCK_CHECK (dlbuf, dlbuf->srcresult, out_flushing);

  if (dlbuf->stream_start_event != NULL) {
    gst_pad_push_event (dlbuf->srcpad, dlbuf->stream_start_event);
    dlbuf->stream_start_event = NULL;
  }
  if (dlbuf->segment_event != NULL) {
    gst_pad_push_event (dlbuf->srcpad, dlbuf->segment_event);
    dlbuf->segment_event = NULL;
  }

  ret = gst_download_buffer_read_buffer (dlbuf, -1, -1, &buffer);
  if (ret != GST_FLOW_OK)
    goto out_flushing;

  /* update the buffering */
  msg = update_buffering (dlbuf);

  g_atomic_int_set (&dlbuf->downstream_may_block, 1);
  GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK (dlbuf);

  if (msg != NULL)
    gst_element_post_message (GST_ELEMENT_CAST (dlbuf), msg);

  ret = gst_pad_push (dlbuf->srcpad, buffer);
  g_atomic_int_set (&dlbuf->downstream_may_block, 0);

  /* need to check for srcresult here as well */
  GST_DOWNLOAD_BUFFER_MUTEX_LOCK_CHECK (dlbuf, dlbuf->srcresult, out_flushing);
  dlbuf->srcresult = ret;
  dlbuf->sinkresult = ret;
  if (ret != GST_FLOW_OK)
    goto out_flushing;
  GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK (dlbuf);

  return;

  /* ERRORS */
out_flushing:
  {
    GstFlowReturn ret = dlbuf->srcresult;

    gst_pad_pause_task (dlbuf->srcpad);
    GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK (dlbuf);
    GST_LOG_OBJECT (dlbuf, "pause task, reason:  %s", gst_flow_get_name (ret));
    /* let app know about us giving up if upstream is not expected to do so */
    if (ret == GST_FLOW_EOS) {
      /* FIXME perform EOS logic, this is really a basesrc operating on a
       * file. */
      gst_pad_push_event (dlbuf->srcpad, gst_event_new_eos ());
    } else if ((ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS)) {
      GST_ELEMENT_ERROR (dlbuf, STREAM, FAILED,
          (_("Internal data flow error.")),
          ("streaming task paused, reason %s (%d)",
              gst_flow_get_name (ret), ret));
      gst_pad_push_event (dlbuf->srcpad, gst_event_new_eos ());
    }
    return;
  }
}

static gboolean
gst_download_buffer_handle_src_event (GstPad * pad, GstObject * parent,
    GstEvent * event)
{
  gboolean res = TRUE;
  GstDownloadBuffer *dlbuf = GST_DOWNLOAD_BUFFER (parent);

#ifndef GST_DISABLE_GST_DEBUG
  GST_DEBUG_OBJECT (dlbuf, "got event %p (%s)",
      event, GST_EVENT_TYPE_NAME (event));
#endif

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_START:
      /* now unblock the getrange function */
      GST_DOWNLOAD_BUFFER_MUTEX_LOCK (dlbuf);
      GST_DEBUG_OBJECT (dlbuf, "flushing");
      dlbuf->srcresult = GST_FLOW_FLUSHING;
      GST_DOWNLOAD_BUFFER_SIGNAL_ADD (dlbuf, -1);
      GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK (dlbuf);

      /* when using a temp file, we eat the event */
      res = TRUE;
      gst_event_unref (event);
      break;
    case GST_EVENT_FLUSH_STOP:
      /* now unblock the getrange function */
      GST_DOWNLOAD_BUFFER_MUTEX_LOCK (dlbuf);
      dlbuf->srcresult = GST_FLOW_OK;
      GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK (dlbuf);

      /* when using a temp file, we eat the event */
      res = TRUE;
      gst_event_unref (event);
      break;
    case GST_EVENT_RECONFIGURE:
      GST_DOWNLOAD_BUFFER_MUTEX_LOCK (dlbuf);
      /* assume downstream is linked now and try to push again */
      if (dlbuf->srcresult == GST_FLOW_NOT_LINKED) {
        dlbuf->srcresult = GST_FLOW_OK;
        dlbuf->sinkresult = GST_FLOW_OK;
        if (GST_PAD_MODE (pad) == GST_PAD_MODE_PUSH) {
          gst_pad_start_task (pad, (GstTaskFunction) gst_download_buffer_loop,
              pad, NULL);
        }
      }
      GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK (dlbuf);

      res = gst_pad_push_event (dlbuf->sinkpad, event);
      break;
    default:
      res = gst_pad_push_event (dlbuf->sinkpad, event);
      break;
  }

  return res;
}

static gboolean
gst_download_buffer_handle_src_query (GstPad * pad, GstObject * parent,
    GstQuery * query)
{
  GstDownloadBuffer *dlbuf;

  dlbuf = GST_DOWNLOAD_BUFFER (parent);

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_POSITION:
    {
      gint64 peer_pos;
      GstFormat format;

      if (!gst_pad_peer_query (dlbuf->sinkpad, query))
        goto peer_failed;

      /* get peer position */
      gst_query_parse_position (query, &format, &peer_pos);

      /* FIXME: this code assumes that there's no discont in the dlbuf */
      switch (format) {
        case GST_FORMAT_BYTES:
          peer_pos -= dlbuf->cur_level.bytes;
          break;
        case GST_FORMAT_TIME:
          peer_pos -= dlbuf->cur_level.time;
          break;
        default:
          GST_WARNING_OBJECT (dlbuf, "dropping query in %s format, don't "
              "know how to adjust value", gst_format_get_name (format));
          return FALSE;
      }
      /* set updated position */
      gst_query_set_position (query, format, peer_pos);
      break;
    }
    case GST_QUERY_DURATION:
    {
      GST_DEBUG_OBJECT (dlbuf, "doing peer query");

      if (!gst_pad_peer_query (dlbuf->sinkpad, query))
        goto peer_failed;

      GST_DEBUG_OBJECT (dlbuf, "peer query success");
      break;
    }
    case GST_QUERY_BUFFERING:
    {
      gint percent;
      gboolean is_buffering;
      GstBufferingMode mode;
      gint avg_in, avg_out;
      gint64 buffering_left;

      GST_DEBUG_OBJECT (dlbuf, "query buffering");

      get_buffering_percent (dlbuf, &is_buffering, &percent);
      gst_query_set_buffering_percent (query, is_buffering, percent);

      get_buffering_stats (dlbuf, percent, &mode, &avg_in, &avg_out,
          &buffering_left);
      gst_query_set_buffering_stats (query, mode, avg_in, avg_out,
          buffering_left);

      {
        /* add ranges for download and ringbuffer buffering */
        GstFormat format;
        gint64 start, stop;
        guint64 write_pos;
        gint64 estimated_total;
        gint64 duration;
        gsize offset, range_start, range_stop;

        GST_DOWNLOAD_BUFFER_MUTEX_LOCK (dlbuf);
        write_pos = dlbuf->write_pos;

        /* get duration of upstream in bytes */
        gst_download_buffer_update_upstream_size (dlbuf);
        duration = dlbuf->upstream_size;

        GST_DEBUG_OBJECT (dlbuf, "percent %d, duration %" G_GINT64_FORMAT
            ", writing %" G_GINT64_FORMAT, percent, duration, write_pos);

        gst_query_parse_buffering_range (query, &format, NULL, NULL, NULL);

        /* fill out the buffered ranges */
        start = offset = 0;
        stop = -1;
        estimated_total = -1;
        while (gst_sparse_file_get_range_after (dlbuf->file, offset,
                &range_start, &range_stop)) {
          gboolean current_range;

          GST_DEBUG_OBJECT (dlbuf,
              "range starting at %" G_GSIZE_FORMAT " and finishing at %"
              G_GSIZE_FORMAT, range_start, range_stop);

          offset = range_stop;

          /* find the range we are currently downloading, we'll remember it
           * after we convert to the target format */
          if (range_start <= write_pos && range_stop >= write_pos) {
            current_range = TRUE;
            /* calculate remaining and total download time */
            if (duration >= range_stop && avg_in > 0.0)
              estimated_total = ((duration - range_stop) * 1000) / avg_in;
          } else
            current_range = FALSE;

          switch (format) {
            case GST_FORMAT_PERCENT:
              /* get our available data relative to the duration */
              if (duration == -1) {
                range_start = 0;
                range_stop = 0;
              } else {
                range_start = gst_util_uint64_scale (GST_FORMAT_PERCENT_MAX,
                    range_start, duration);
                range_stop = gst_util_uint64_scale (GST_FORMAT_PERCENT_MAX,
                    range_stop, duration);
              }
              break;
            case GST_FORMAT_BYTES:
              break;
            default:
              range_start = -1;
              range_stop = -1;
              break;
          }

          if (current_range) {
            /* we are currently downloading this range */
            start = range_start;
            stop = range_stop;
          }
          GST_DEBUG_OBJECT (dlbuf,
              "range to format: %" G_GSIZE_FORMAT " - %" G_GSIZE_FORMAT,
              range_start, range_stop);
          if (range_start == range_stop)
            continue;
          gst_query_add_buffering_range (query, range_start, range_stop);
        }

        GST_DEBUG_OBJECT (dlbuf, "estimated-total %" G_GINT64_FORMAT,
            estimated_total);

        gst_query_set_buffering_range (query, format, start, stop,
            estimated_total);

        GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK (dlbuf);
      }
      break;
    }
    case GST_QUERY_SCHEDULING:
    {
      GstSchedulingFlags flags = 0;

      if (!gst_pad_peer_query (dlbuf->sinkpad, query))
        goto peer_failed;

      gst_query_parse_scheduling (query, &flags, NULL, NULL, NULL);

      /* we can operate in pull mode when we are using a tempfile */
      flags |= GST_SCHEDULING_FLAG_SEEKABLE;
      gst_query_set_scheduling (query, flags, 0, -1, 0);
      gst_query_add_scheduling_mode (query, GST_PAD_MODE_PULL);
      gst_query_add_scheduling_mode (query, GST_PAD_MODE_PUSH);
      break;
    }
    default:
      /* peer handled other queries */
      if (!gst_pad_query_default (pad, parent, query))
        goto peer_failed;
      break;
  }

  return TRUE;

  /* ERRORS */
peer_failed:
  {
    GST_DEBUG_OBJECT (dlbuf, "failed peer query");
    return FALSE;
  }
}

static gboolean
gst_download_buffer_handle_query (GstElement * element, GstQuery * query)
{
  GstDownloadBuffer *dlbuf = GST_DOWNLOAD_BUFFER (element);

  /* simply forward to the srcpad query function */
  return gst_download_buffer_handle_src_query (dlbuf->srcpad,
      GST_OBJECT_CAST (element), query);
}

static GstFlowReturn
gst_download_buffer_get_range (GstPad * pad, GstObject * parent, guint64 offset,
    guint length, GstBuffer ** buffer)
{
  GstDownloadBuffer *dlbuf;
  GstFlowReturn ret;
  GstMessage *msg = NULL;

  dlbuf = GST_DOWNLOAD_BUFFER_CAST (parent);

  GST_DOWNLOAD_BUFFER_MUTEX_LOCK_CHECK (dlbuf, dlbuf->srcresult, out_flushing);
  /* FIXME - function will block when the range is not yet available */
  ret = gst_download_buffer_read_buffer (dlbuf, offset, length, buffer);
  /* update the buffering */
  msg = update_buffering (dlbuf);

  GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK (dlbuf);

  if (msg != NULL)
    gst_element_post_message (GST_ELEMENT_CAST (dlbuf), msg);

  return ret;

  /* ERRORS */
out_flushing:
  {
    ret = dlbuf->srcresult;

    GST_DEBUG_OBJECT (dlbuf, "we are flushing");
    GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK (dlbuf);
    return ret;
  }
}

/* sink currently only operates in push mode */
static gboolean
gst_download_buffer_sink_activate_mode (GstPad * pad, GstObject * parent,
    GstPadMode mode, gboolean active)
{
  gboolean result;
  GstDownloadBuffer *dlbuf;

  dlbuf = GST_DOWNLOAD_BUFFER (parent);

  switch (mode) {
    case GST_PAD_MODE_PUSH:
      if (active) {
        GST_DOWNLOAD_BUFFER_MUTEX_LOCK (dlbuf);
        GST_DEBUG_OBJECT (dlbuf, "activating push mode");
        dlbuf->srcresult = GST_FLOW_OK;
        dlbuf->sinkresult = GST_FLOW_OK;
        dlbuf->unexpected = FALSE;
        reset_rate_timer (dlbuf);
        GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK (dlbuf);
      } else {
        /* unblock chain function */
        GST_DOWNLOAD_BUFFER_MUTEX_LOCK (dlbuf);
        GST_DEBUG_OBJECT (dlbuf, "deactivating push mode");
        dlbuf->srcresult = GST_FLOW_FLUSHING;
        dlbuf->sinkresult = GST_FLOW_FLUSHING;
        GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK (dlbuf);

        /* wait until it is unblocked and clean up */
        GST_PAD_STREAM_LOCK (pad);
        GST_DOWNLOAD_BUFFER_MUTEX_LOCK (dlbuf);
        gst_download_buffer_locked_flush (dlbuf, TRUE, FALSE);
        GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK (dlbuf);
        GST_PAD_STREAM_UNLOCK (pad);
      }
      result = TRUE;
      break;
    default:
      result = FALSE;
      break;
  }
  return result;
}

/* src operating in push mode, we start a task on the source pad that pushes out
 * buffers from the dlbuf */
static gboolean
gst_download_buffer_src_activate_push (GstPad * pad, GstObject * parent,
    gboolean active)
{
  gboolean result = FALSE;
  GstDownloadBuffer *dlbuf;

  dlbuf = GST_DOWNLOAD_BUFFER (parent);

  if (active) {
    GST_DOWNLOAD_BUFFER_MUTEX_LOCK (dlbuf);
    GST_DEBUG_OBJECT (dlbuf, "activating push mode");
    dlbuf->srcresult = GST_FLOW_OK;
    dlbuf->sinkresult = GST_FLOW_OK;
    dlbuf->unexpected = FALSE;
    result =
        gst_pad_start_task (pad, (GstTaskFunction) gst_download_buffer_loop,
        pad, NULL);
    GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK (dlbuf);
  } else {
    /* unblock loop function */
    GST_DOWNLOAD_BUFFER_MUTEX_LOCK (dlbuf);
    GST_DEBUG_OBJECT (dlbuf, "deactivating push mode");
    dlbuf->srcresult = GST_FLOW_FLUSHING;
    dlbuf->sinkresult = GST_FLOW_FLUSHING;
    /* the item add signal will unblock */
    GST_DOWNLOAD_BUFFER_SIGNAL_ADD (dlbuf, -1);
    GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK (dlbuf);

    /* step 2, make sure streaming finishes */
    result = gst_pad_stop_task (pad);
  }

  return result;
}

/* pull mode, downstream will call our getrange function */
static gboolean
gst_download_buffer_src_activate_pull (GstPad * pad, GstObject * parent,
    gboolean active)
{
  gboolean result;
  GstDownloadBuffer *dlbuf;

  dlbuf = GST_DOWNLOAD_BUFFER (parent);

  if (active) {
    GST_DOWNLOAD_BUFFER_MUTEX_LOCK (dlbuf);
    /* open the temp file now */
    result = gst_download_buffer_open_temp_location_file (dlbuf);
    GST_DEBUG_OBJECT (dlbuf, "activating pull mode");
    dlbuf->srcresult = GST_FLOW_OK;
    dlbuf->sinkresult = GST_FLOW_OK;
    dlbuf->unexpected = FALSE;
    dlbuf->upstream_size = 0;
    GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK (dlbuf);
  } else {
    GST_DOWNLOAD_BUFFER_MUTEX_LOCK (dlbuf);
    GST_DEBUG_OBJECT (dlbuf, "deactivating pull mode");
    dlbuf->srcresult = GST_FLOW_FLUSHING;
    dlbuf->sinkresult = GST_FLOW_FLUSHING;
    /* this will unlock getrange */
    GST_DOWNLOAD_BUFFER_SIGNAL_ADD (dlbuf, -1);
    result = TRUE;
    GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK (dlbuf);
  }

  return result;
}

static gboolean
gst_download_buffer_src_activate_mode (GstPad * pad, GstObject * parent,
    GstPadMode mode, gboolean active)
{
  gboolean res;

  switch (mode) {
    case GST_PAD_MODE_PULL:
      res = gst_download_buffer_src_activate_pull (pad, parent, active);
      break;
    case GST_PAD_MODE_PUSH:
      res = gst_download_buffer_src_activate_push (pad, parent, active);
      break;
    default:
      GST_LOG_OBJECT (pad, "unknown activation mode %d", mode);
      res = FALSE;
      break;
  }
  return res;
}

static GstStateChangeReturn
gst_download_buffer_change_state (GstElement * element,
    GstStateChange transition)
{
  GstDownloadBuffer *dlbuf;
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;

  dlbuf = GST_DOWNLOAD_BUFFER (element);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      GST_DOWNLOAD_BUFFER_MUTEX_LOCK (dlbuf);
      if (!gst_download_buffer_open_temp_location_file (dlbuf))
        ret = GST_STATE_CHANGE_FAILURE;
      gst_event_replace (&dlbuf->stream_start_event, NULL);
      gst_event_replace (&dlbuf->segment_event, NULL);
      GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK (dlbuf);
      break;
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      break;
    default:
      break;
  }

  if (ret == GST_STATE_CHANGE_FAILURE)
    return ret;

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

  if (ret == GST_STATE_CHANGE_FAILURE)
    return ret;

  switch (transition) {
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      GST_DOWNLOAD_BUFFER_MUTEX_LOCK (dlbuf);
      gst_download_buffer_close_temp_location_file (dlbuf);
      gst_event_replace (&dlbuf->stream_start_event, NULL);
      gst_event_replace (&dlbuf->segment_event, NULL);
      GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK (dlbuf);
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      break;
    default:
      break;
  }

  return ret;
}

#define CAPACITY_CHANGE(elem) \
  update_buffering (elem);

static void
gst_download_buffer_set_temp_template (GstDownloadBuffer * dlbuf,
    const gchar * template)
{
  GstState state;

  /* the element must be stopped in order to do this */
  GST_OBJECT_LOCK (dlbuf);
  state = GST_STATE (dlbuf);
  if (state != GST_STATE_READY && state != GST_STATE_NULL)
    goto wrong_state;
  GST_OBJECT_UNLOCK (dlbuf);

  /* set new location */
  g_free (dlbuf->temp_template);
  dlbuf->temp_template = g_strdup (template);

  return;

/* ERROR */
wrong_state:
  {
    GST_WARNING_OBJECT (dlbuf, "setting temp-template property in wrong state");
    GST_OBJECT_UNLOCK (dlbuf);
  }
}

static void
gst_download_buffer_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec)
{
  GstDownloadBuffer *dlbuf = GST_DOWNLOAD_BUFFER (object);
  GstMessage *msg = NULL;

  /* someone could change levels here, and since this
   * affects the get/put funcs, we need to lock for safety. */
  GST_DOWNLOAD_BUFFER_MUTEX_LOCK (dlbuf);

  switch (prop_id) {
    case PROP_MAX_SIZE_BYTES:
      dlbuf->max_level.bytes = g_value_get_uint (value);
      msg = CAPACITY_CHANGE (dlbuf);
      break;
    case PROP_MAX_SIZE_TIME:
      dlbuf->max_level.time = g_value_get_uint64 (value);
      msg = CAPACITY_CHANGE (dlbuf);
      break;
    case PROP_LOW_PERCENT:
      dlbuf->low_percent = g_value_get_int (value);
      break;
    case PROP_HIGH_PERCENT:
      dlbuf->high_percent = g_value_get_int (value);
      break;
    case PROP_TEMP_TEMPLATE:
      gst_download_buffer_set_temp_template (dlbuf, g_value_get_string (value));
      break;
    case PROP_TEMP_REMOVE:
      dlbuf->temp_remove = g_value_get_boolean (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }

  GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK (dlbuf);

  if (msg != NULL)
    gst_element_post_message (GST_ELEMENT_CAST (dlbuf), msg);

}

static void
gst_download_buffer_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec)
{
  GstDownloadBuffer *dlbuf = GST_DOWNLOAD_BUFFER (object);

  GST_DOWNLOAD_BUFFER_MUTEX_LOCK (dlbuf);

  switch (prop_id) {
    case PROP_MAX_SIZE_BYTES:
      g_value_set_uint (value, dlbuf->max_level.bytes);
      break;
    case PROP_MAX_SIZE_TIME:
      g_value_set_uint64 (value, dlbuf->max_level.time);
      break;
    case PROP_LOW_PERCENT:
      g_value_set_int (value, dlbuf->low_percent);
      break;
    case PROP_HIGH_PERCENT:
      g_value_set_int (value, dlbuf->high_percent);
      break;
    case PROP_TEMP_TEMPLATE:
      g_value_set_string (value, dlbuf->temp_template);
      break;
    case PROP_TEMP_LOCATION:
      g_value_set_string (value, dlbuf->temp_location);
      break;
    case PROP_TEMP_REMOVE:
      g_value_set_boolean (value, dlbuf->temp_remove);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }

  GST_DOWNLOAD_BUFFER_MUTEX_UNLOCK (dlbuf);
}
