/* 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 emitting 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
#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_static_pad_template (gstelement_class, &srctemplate);
  gst_element_class_add_static_pad_template (gstelement_class, &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 file */

  /* 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_FLOW_ERROR (dlbuf, 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);
}
