/* GStreamer Split Demuxer bin that recombines files created by
 * the splitmuxsink element.
 *
 * Copyright (C) <2014> Jan Schmidt <jan@centricular.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

/**
 * SECTION:element-splitmuxsrc
 * @short_description: Split Demuxer bin that recombines files created by
 * the splitmuxsink element.
 *
 * This element reads a set of input files created by the splitmuxsink element
 * containing contiguous elementary streams split across multiple files.
 *
 * This element is similar to splitfilesrc, except that it recombines the
 * streams in each file part at the demuxed elementary level, rather than
 * as a single larger bytestream.
 *
 * <refsect2>
 * <title>Example pipelines</title>
 * |[
 * gst-launch-1.0 splitmuxsrc location=video*.mov ! decodebin ! xvimagesink
 * ]| Demux each file part and output the video stream as one continuous stream
 * |[
 * gst-launch-1.0 playbin uri="splitmux://path/to/foo.mp4.*"
 * ]| Play back a set of files created by splitmuxsink
 * </refsect2>
 */

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

#include <string.h>
#include "gstsplitmuxsrc.h"
#include "gstsplitutils.h"

#include "../../gst-libs/gst/gst-i18n-plugin.h"

GST_DEBUG_CATEGORY (splitmux_debug);
#define GST_CAT_DEFAULT splitmux_debug

enum
{
  PROP_0,
  PROP_LOCATION
};

enum
{
  SIGNAL_FORMAT_LOCATION,
  SIGNAL_LAST
};

static guint signals[SIGNAL_LAST];

static GstStaticPadTemplate video_src_template =
GST_STATIC_PAD_TEMPLATE ("video",
    GST_PAD_SRC,
    GST_PAD_SOMETIMES,
    GST_STATIC_CAPS_ANY);

static GstStaticPadTemplate audio_src_template =
GST_STATIC_PAD_TEMPLATE ("audio_%u",
    GST_PAD_SRC,
    GST_PAD_SOMETIMES,
    GST_STATIC_CAPS_ANY);

static GstStaticPadTemplate subtitle_src_template =
GST_STATIC_PAD_TEMPLATE ("subtitle_%u",
    GST_PAD_SRC,
    GST_PAD_SOMETIMES,
    GST_STATIC_CAPS_ANY);

static GstStateChangeReturn gst_splitmux_src_change_state (GstElement *
    element, GstStateChange transition);
static void gst_splitmux_src_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_splitmux_src_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static void gst_splitmux_src_dispose (GObject * object);
static void gst_splitmux_src_finalize (GObject * object);
static gboolean gst_splitmux_src_start (GstSplitMuxSrc * splitmux);
static gboolean gst_splitmux_src_stop (GstSplitMuxSrc * splitmux);
static void splitmux_src_pad_constructed (GObject * pad);
static gboolean splitmux_src_pad_event (GstPad * pad, GstObject * parent,
    GstEvent * event);
static gboolean splitmux_src_pad_query (GstPad * pad, GstObject * parent,
    GstQuery * query);
static void splitmux_src_uri_handler_init (gpointer g_iface,
    gpointer iface_data);


static GstPad *gst_splitmux_find_output_pad (GstSplitMuxPartReader * part,
    GstPad * pad, GstSplitMuxSrc * splitmux);
static void gst_splitmux_part_prepared (GstSplitMuxPartReader * reader,
    GstSplitMuxSrc * splitmux);
static gboolean gst_splitmux_end_of_part (GstSplitMuxSrc * splitmux,
    SplitMuxSrcPad * pad);
static gboolean gst_splitmux_check_new_caps (SplitMuxSrcPad * splitpad,
    GstEvent * event);

#define _do_init \
    G_IMPLEMENT_INTERFACE(GST_TYPE_URI_HANDLER, splitmux_src_uri_handler_init);
#define gst_splitmux_src_parent_class parent_class

G_DEFINE_TYPE_EXTENDED (GstSplitMuxSrc, gst_splitmux_src, GST_TYPE_BIN, 0,
    _do_init);

static GstURIType
splitmux_src_uri_get_type (GType type)
{
  return GST_URI_SRC;
}

static const gchar *const *
splitmux_src_uri_get_protocols (GType type)
{
  static const gchar *protocols[] = { "splitmux", NULL };

  return protocols;
}

static gchar *
splitmux_src_uri_get_uri (GstURIHandler * handler)
{
  GstSplitMuxSrc *splitmux = GST_SPLITMUX_SRC (handler);
  gchar *ret = NULL;

  GST_OBJECT_LOCK (splitmux);
  if (splitmux->location)
    ret = g_strdup_printf ("splitmux://%s", splitmux->location);
  GST_OBJECT_UNLOCK (splitmux);
  return ret;
}

static gboolean
splitmux_src_uri_set_uri (GstURIHandler * handler, const gchar * uri,
    GError ** err)
{
  GstSplitMuxSrc *splitmux = GST_SPLITMUX_SRC (handler);
  gchar *protocol, *location;

  protocol = gst_uri_get_protocol (uri);
  if (protocol == NULL || !g_str_equal (protocol, "splitmux"))
    goto wrong_uri;
  g_free (protocol);

  location = gst_uri_get_location (uri);
  GST_OBJECT_LOCK (splitmux);
  g_free (splitmux->location);
  splitmux->location = location;
  GST_OBJECT_UNLOCK (splitmux);

  return TRUE;

wrong_uri:
  g_free (protocol);
  GST_ELEMENT_ERROR (splitmux, RESOURCE, READ, (NULL),
      ("Error parsing uri %s", uri));
  g_set_error_literal (err, GST_URI_ERROR, GST_URI_ERROR_BAD_URI,
      "Could not parse splitmux URI");
  return FALSE;
}

static void
splitmux_src_uri_handler_init (gpointer g_iface, gpointer iface_data)
{
  GstURIHandlerInterface *iface = (GstURIHandlerInterface *) (g_iface);

  iface->get_type = splitmux_src_uri_get_type;
  iface->get_protocols = splitmux_src_uri_get_protocols;
  iface->set_uri = splitmux_src_uri_set_uri;
  iface->get_uri = splitmux_src_uri_get_uri;
}


static void
gst_splitmux_src_class_init (GstSplitMuxSrcClass * klass)
{
  GObjectClass *gobject_class = (GObjectClass *) klass;
  GstElementClass *gstelement_class = (GstElementClass *) klass;

  gobject_class->set_property = gst_splitmux_src_set_property;
  gobject_class->get_property = gst_splitmux_src_get_property;
  gobject_class->dispose = gst_splitmux_src_dispose;
  gobject_class->finalize = gst_splitmux_src_finalize;

  gst_element_class_set_static_metadata (gstelement_class,
      "Split File Demuxing Bin", "Generic/Bin/Demuxer",
      "Source that reads a set of files created by splitmuxsink",
      "Jan Schmidt <jan@centricular.com>");

  gst_element_class_add_static_pad_template (gstelement_class,
      &video_src_template);
  gst_element_class_add_static_pad_template (gstelement_class,
      &audio_src_template);
  gst_element_class_add_static_pad_template (gstelement_class,
      &subtitle_src_template);

  gstelement_class->change_state =
      GST_DEBUG_FUNCPTR (gst_splitmux_src_change_state);

  g_object_class_install_property (gobject_class, PROP_LOCATION,
      g_param_spec_string ("location", "File Input Pattern",
          "Glob pattern for the location of the files to read", NULL,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstSplitMuxSrc::format-location:
   * @splitmux: the #GstSplitMuxSrc
   *
   * Returns: A NULL-terminated sorted array of strings containing the
   *   filenames of the input files. The array will be freed internally
   *   using g_strfreev()
   *
   * Since: 1.8
   */
  signals[SIGNAL_FORMAT_LOCATION] =
      g_signal_new ("format-location", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_STRV, 0);
}

static void
gst_splitmux_src_init (GstSplitMuxSrc * splitmux)
{
  g_mutex_init (&splitmux->lock);
  g_mutex_init (&splitmux->pads_lock);
  splitmux->total_duration = GST_CLOCK_TIME_NONE;
  gst_segment_init (&splitmux->play_segment, GST_FORMAT_TIME);
}

static void
gst_splitmux_src_dispose (GObject * object)
{
  GstSplitMuxSrc *splitmux = GST_SPLITMUX_SRC (object);
  GList *cur;

  SPLITMUX_SRC_PADS_LOCK (splitmux);

  for (cur = g_list_first (splitmux->pads);
      cur != NULL; cur = g_list_next (cur)) {
    GstPad *pad = GST_PAD (cur->data);
    gst_element_remove_pad (GST_ELEMENT (splitmux), pad);
  }
  g_list_free (splitmux->pads);
  splitmux->pads = NULL;
  SPLITMUX_SRC_PADS_UNLOCK (splitmux);

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

static void
gst_splitmux_src_finalize (GObject * object)
{
  GstSplitMuxSrc *splitmux = GST_SPLITMUX_SRC (object);
  g_mutex_clear (&splitmux->lock);
  g_mutex_clear (&splitmux->pads_lock);
  g_free (splitmux->location);

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

static void
gst_splitmux_src_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstSplitMuxSrc *splitmux = GST_SPLITMUX_SRC (object);

  switch (prop_id) {
    case PROP_LOCATION:{
      GST_OBJECT_LOCK (splitmux);
      g_free (splitmux->location);
      splitmux->location = g_value_dup_string (value);
      GST_OBJECT_UNLOCK (splitmux);
      break;
    }
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_splitmux_src_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstSplitMuxSrc *splitmux = GST_SPLITMUX_SRC (object);

  switch (prop_id) {
    case PROP_LOCATION:
      GST_OBJECT_LOCK (splitmux);
      g_value_set_string (value, splitmux->location);
      GST_OBJECT_UNLOCK (splitmux);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static GstStateChangeReturn
gst_splitmux_src_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn ret;
  GstSplitMuxSrc *splitmux = (GstSplitMuxSrc *) element;

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:{
      break;
    }
    case GST_STATE_CHANGE_READY_TO_PAUSED:{
      if (!gst_splitmux_src_start (splitmux))
        return GST_STATE_CHANGE_FAILURE;
      break;
    }
    case GST_STATE_CHANGE_PAUSED_TO_READY:
    case GST_STATE_CHANGE_READY_TO_NULL:
      /* Make sure the element will shut down */
      if (!gst_splitmux_src_stop (splitmux))
        return GST_STATE_CHANGE_FAILURE;
      break;
    default:
      break;
  }

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

  return ret;
}

static GstSplitMuxPartReader *
gst_splitmux_part_create (GstSplitMuxSrc * splitmux, char *filename)
{
  GstSplitMuxPartReader *r;

  r = g_object_new (GST_TYPE_SPLITMUX_PART_READER, NULL);

  g_signal_connect (r, "prepared", (GCallback) gst_splitmux_part_prepared,
      splitmux);

  gst_splitmux_part_reader_set_callbacks (r, splitmux,
      (GstSplitMuxPartReaderPadCb) gst_splitmux_find_output_pad);
  gst_splitmux_part_reader_set_location (r, filename);

  return r;
}

static gboolean
gst_splitmux_check_new_caps (SplitMuxSrcPad * splitpad, GstEvent * event)
{
  GstCaps *curcaps = gst_pad_get_current_caps ((GstPad *) (splitpad));
  GstCaps *newcaps;
  GstCaps *tmpcaps;
  GstCaps *tmpcurcaps;

  GstStructure *s;
  gboolean res = TRUE;

  gst_event_parse_caps (event, &newcaps);

  GST_LOG_OBJECT (splitpad, "Comparing caps %" GST_PTR_FORMAT
      " and %" GST_PTR_FORMAT, curcaps, newcaps);

  if (curcaps == NULL)
    return TRUE;

  /* If caps are exactly equal exit early */
  if (gst_caps_is_equal (curcaps, newcaps)) {
    gst_caps_unref (curcaps);
    return FALSE;
  }

  /* More extensive check, ignore changes in framerate, because
   * demuxers get that wrong */
  tmpcaps = gst_caps_copy (newcaps);
  s = gst_caps_get_structure (tmpcaps, 0);
  gst_structure_remove_field (s, "framerate");

  tmpcurcaps = gst_caps_copy (curcaps);
  gst_caps_unref (curcaps);
  s = gst_caps_get_structure (tmpcurcaps, 0);
  gst_structure_remove_field (s, "framerate");

  /* Now check if these filtered caps are equal */
  if (gst_caps_is_equal (tmpcurcaps, tmpcaps)) {
    GST_INFO_OBJECT (splitpad, "Ignoring framerate-only caps change");
    res = FALSE;
  }

  gst_caps_unref (tmpcaps);
  gst_caps_unref (tmpcurcaps);
  return res;
}

static void
gst_splitmux_handle_event (GstSplitMuxSrc * splitmux,
    SplitMuxSrcPad * splitpad, GstPad * part_pad, GstEvent * event)
{
  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_STREAM_START:{
      if (splitpad->sent_stream_start)
        goto drop_event;
      splitpad->sent_stream_start = TRUE;
      break;
    }
    case GST_EVENT_EOS:{
      if (gst_splitmux_end_of_part (splitmux, splitpad))
        // Continuing to next part, drop the EOS
        goto drop_event;
      if (splitmux->segment_seqnum)
        gst_event_set_seqnum (event, splitmux->segment_seqnum);
      break;
    }
    case GST_EVENT_SEGMENT:{
      GstClockTime duration;
      GstSegment seg;

      gst_event_copy_segment (event, &seg);

      splitpad->segment.position = seg.position;

      if (splitpad->sent_segment)
        goto drop_event;        /* We already forwarded a segment event */

      /* Calculate output segment */
      GST_LOG_OBJECT (splitpad, "Pad seg %" GST_SEGMENT_FORMAT
          " got seg %" GST_SEGMENT_FORMAT
          " play seg %" GST_SEGMENT_FORMAT,
          &splitpad->segment, &seg, &splitmux->play_segment);

      /* If playing forward, take the stop time from the overall
       * seg or play_segment */
      if (splitmux->play_segment.rate > 0.0) {
        if (splitmux->play_segment.stop != -1)
          seg.stop = splitmux->play_segment.stop;
        else
          seg.stop = splitpad->segment.stop;
      } else {
        /* Reverse playback from stop time to start time */
        /* See if an end point was requested in the seek */
        if (splitmux->play_segment.start != -1) {
          seg.start = splitmux->play_segment.start;
          seg.time = splitmux->play_segment.time;
        } else {
          seg.start = splitpad->segment.start;
          seg.time = splitpad->segment.time;
        }
      }

      GST_OBJECT_LOCK (splitmux);
      duration = splitmux->total_duration;
      GST_OBJECT_UNLOCK (splitmux);

      if (duration > 0)
        seg.duration = duration;
      else
        seg.duration = GST_CLOCK_TIME_NONE;

      GST_INFO_OBJECT (splitpad,
          "Forwarding segment %" GST_SEGMENT_FORMAT, &seg);

      gst_event_unref (event);
      event = gst_event_new_segment (&seg);
      if (splitmux->segment_seqnum)
        gst_event_set_seqnum (event, splitmux->segment_seqnum);
      splitpad->sent_segment = TRUE;
      break;
    }
    case GST_EVENT_CAPS:{
      if (!gst_splitmux_check_new_caps (splitpad, event))
        goto drop_event;
      splitpad->sent_caps = TRUE;
      break;
    }
    default:
      break;
  }

  gst_pad_push_event ((GstPad *) (splitpad), event);
  return;
drop_event:
  gst_event_unref (event);
  return;
}

static GstFlowReturn
gst_splitmux_handle_buffer (GstSplitMuxSrc * splitmux,
    SplitMuxSrcPad * splitpad, GstBuffer * buf)
{
  GstFlowReturn ret;

  if (splitpad->clear_next_discont) {
    GST_LOG_OBJECT (splitpad, "Clearing discont flag on buffer");
    GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
    splitpad->clear_next_discont = FALSE;
  }
  if (splitpad->set_next_discont) {
    GST_LOG_OBJECT (splitpad, "Setting discont flag on buffer");
    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
    splitpad->set_next_discont = FALSE;
  }

  ret = gst_pad_push (GST_PAD_CAST (splitpad), buf);

  GST_LOG_OBJECT (splitpad, "Pad push returned %d", ret);
  return ret;
}

static void
gst_splitmux_pad_loop (GstPad * pad)
{
  /* Get one event/buffer from the associated part and push */
  SplitMuxSrcPad *splitpad = (SplitMuxSrcPad *) (pad);
  GstSplitMuxSrc *splitmux = (GstSplitMuxSrc *) gst_pad_get_parent (pad);
  GstDataQueueItem *item = NULL;
  GstSplitMuxPartReader *reader = splitpad->reader;
  GstPad *part_pad;
  GstFlowReturn ret;

  GST_OBJECT_LOCK (splitpad);
  if (splitpad->part_pad == NULL) {
    GST_OBJECT_UNLOCK (splitpad);
    return;
  }
  part_pad = gst_object_ref (splitpad->part_pad);
  GST_OBJECT_UNLOCK (splitpad);

  GST_LOG_OBJECT (splitpad, "Popping data queue item from %" GST_PTR_FORMAT
      " pad %" GST_PTR_FORMAT, reader, part_pad);
  ret = gst_splitmux_part_reader_pop (reader, part_pad, &item);
  if (ret == GST_FLOW_ERROR)
    goto error;
  if (ret == GST_FLOW_FLUSHING || item == NULL)
    goto flushing;

  GST_DEBUG_OBJECT (splitpad, "Got data queue item %" GST_PTR_FORMAT,
      item->object);

  if (GST_IS_EVENT (item->object)) {
    GstEvent *event = (GstEvent *) (item->object);
    gst_splitmux_handle_event (splitmux, splitpad, part_pad, event);
  } else {
    GstBuffer *buf = (GstBuffer *) (item->object);
    GstFlowReturn ret = gst_splitmux_handle_buffer (splitmux, splitpad, buf);
    if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)) {
      /* Stop immediately on error or flushing */
      GST_INFO_OBJECT (splitpad, "Stopping due to pad_push() result %d", ret);
      gst_pad_pause_task (pad);
      if (ret < GST_FLOW_EOS || ret == GST_FLOW_NOT_LINKED) {
        GST_ELEMENT_FLOW_ERROR (splitmux, ret);
      }
    }
  }
  g_slice_free (GstDataQueueItem, item);

  gst_object_unref (part_pad);
  gst_object_unref (splitmux);
  return;

error:
  /* Fall through */
  GST_ELEMENT_ERROR (splitmux, RESOURCE, OPEN_READ, (NULL),
      ("Error reading part file %s", GST_STR_NULL (reader->path)));
flushing:
  gst_pad_pause_task (pad);
  gst_object_unref (part_pad);
  gst_object_unref (splitmux);
  return;
}

static gboolean
gst_splitmux_src_activate_part (GstSplitMuxSrc * splitmux, guint part,
    GstSeekFlags extra_flags)
{
  GList *cur;

  GST_DEBUG_OBJECT (splitmux, "Activating part %d", part);

  splitmux->cur_part = part;
  if (!gst_splitmux_part_reader_activate (splitmux->parts[part],
          &splitmux->play_segment, extra_flags))
    return FALSE;

  SPLITMUX_SRC_PADS_LOCK (splitmux);
  for (cur = g_list_first (splitmux->pads);
      cur != NULL; cur = g_list_next (cur)) {
    SplitMuxSrcPad *splitpad = (SplitMuxSrcPad *) (cur->data);
    splitpad->cur_part = part;
    splitpad->reader = splitmux->parts[splitpad->cur_part];
    if (splitpad->part_pad)
      gst_object_unref (splitpad->part_pad);
    splitpad->part_pad =
        gst_splitmux_part_reader_lookup_pad (splitpad->reader,
        (GstPad *) (splitpad));

    /* Make sure we start with a DISCONT */
    splitpad->set_next_discont = TRUE;
    splitpad->clear_next_discont = FALSE;

    gst_pad_start_task (GST_PAD (splitpad),
        (GstTaskFunction) gst_splitmux_pad_loop, splitpad, NULL);
  }
  SPLITMUX_SRC_PADS_UNLOCK (splitmux);

  return TRUE;
}

static gboolean
gst_splitmux_src_start (GstSplitMuxSrc * splitmux)
{
  gboolean ret = FALSE;
  GError *err = NULL;
  gchar *basename = NULL;
  gchar *dirname = NULL;
  gchar **files;
  GstClockTime next_offset = 0;
  guint i;
  GstClockTime total_duration = 0;

  GST_DEBUG_OBJECT (splitmux, "Starting");

  g_signal_emit (splitmux, signals[SIGNAL_FORMAT_LOCATION], 0, &files);

  if (files == NULL || *files == NULL) {
    GST_OBJECT_LOCK (splitmux);
    if (splitmux->location != NULL && splitmux->location[0] != '\0') {
      basename = g_path_get_basename (splitmux->location);
      dirname = g_path_get_dirname (splitmux->location);
    }
    GST_OBJECT_UNLOCK (splitmux);

    g_strfreev (files);
    files = gst_split_util_find_files (dirname, basename, &err);

    if (files == NULL || *files == NULL)
      goto no_files;
  }

  SPLITMUX_SRC_LOCK (splitmux);
  splitmux->pads_complete = FALSE;
  splitmux->running = TRUE;
  SPLITMUX_SRC_UNLOCK (splitmux);

  splitmux->num_parts = g_strv_length (files);

  splitmux->parts = g_new0 (GstSplitMuxPartReader *, splitmux->num_parts);

  for (i = 0; i < splitmux->num_parts; i++) {
    splitmux->parts[i] = gst_splitmux_part_create (splitmux, files[i]);
    if (splitmux->parts[i] == NULL)
      break;

    /* Figure out the next offset - the smallest one */
    gst_splitmux_part_reader_set_start_offset (splitmux->parts[i], next_offset);
    if (!gst_splitmux_part_reader_prepare (splitmux->parts[i])) {
      GST_WARNING_OBJECT (splitmux,
          "Failed to prepare file part %s. Cannot play past there.", files[i]);
      GST_ELEMENT_WARNING (splitmux, RESOURCE, READ, (NULL),
          ("Failed to prepare file part %s. Cannot play past there.",
              files[i]));
      gst_splitmux_part_reader_unprepare (splitmux->parts[i]);
      g_object_unref (splitmux->parts[i]);
      splitmux->parts[i] = NULL;
      break;
    }

    /* Extend our total duration to cover this part */
    total_duration =
        next_offset +
        gst_splitmux_part_reader_get_duration (splitmux->parts[i]);
    splitmux->play_segment.duration = total_duration;

    next_offset = gst_splitmux_part_reader_get_end_offset (splitmux->parts[i]);
  }

  /* Update total_duration state variable */
  GST_OBJECT_LOCK (splitmux);
  splitmux->total_duration = total_duration;
  GST_OBJECT_UNLOCK (splitmux);

  /* Store how many parts we actually created */
  splitmux->num_parts = i;

  if (splitmux->num_parts < 1)
    goto failed_part;

  /* All done preparing, activate the first part */
  GST_INFO_OBJECT (splitmux,
      "All parts prepared. Total duration %" GST_TIME_FORMAT
      " Activating first part", GST_TIME_ARGS (total_duration));
  ret = gst_splitmux_src_activate_part (splitmux, 0, GST_SEEK_FLAG_NONE);
  if (ret == FALSE)
    goto failed_first_part;
done:
  if (err != NULL)
    g_error_free (err);
  g_strfreev (files);
  g_free (basename);
  g_free (dirname);

  return ret;

/* ERRORS */
no_files:
  {
    GST_ELEMENT_ERROR (splitmux, RESOURCE, OPEN_READ, ("%s", err->message),
        ("Failed to find files in '%s' for pattern '%s'",
            GST_STR_NULL (dirname), GST_STR_NULL (basename)));
    goto done;
  }
failed_part:
  {
    GST_ELEMENT_ERROR (splitmux, RESOURCE, OPEN_READ, (NULL),
        ("Failed to open any files for reading"));
    goto done;
  }
failed_first_part:
  {
    GST_ELEMENT_ERROR (splitmux, RESOURCE, OPEN_READ, (NULL),
        ("Failed to activate first part for playback"));
    goto done;
  }
}

static gboolean
gst_splitmux_src_stop (GstSplitMuxSrc * splitmux)
{
  gboolean ret = TRUE;
  guint i;
  GList *cur, *pads_list;

  SPLITMUX_SRC_LOCK (splitmux);
  if (!splitmux->running)
    goto out;

  GST_DEBUG_OBJECT (splitmux, "Stopping");

  /* Stop and destroy all parts  */
  for (i = 0; i < splitmux->num_parts; i++) {
    if (splitmux->parts[i] == NULL)
      continue;
    gst_splitmux_part_reader_unprepare (splitmux->parts[i]);
    g_object_unref (splitmux->parts[i]);
    splitmux->parts[i] = NULL;
  }

  SPLITMUX_SRC_PADS_LOCK (splitmux);
  pads_list = splitmux->pads;
  splitmux->pads = NULL;
  SPLITMUX_SRC_PADS_UNLOCK (splitmux);

  SPLITMUX_SRC_UNLOCK (splitmux);
  for (cur = g_list_first (pads_list); cur != NULL; cur = g_list_next (cur)) {
    SplitMuxSrcPad *tmp = (SplitMuxSrcPad *) (cur->data);
    gst_pad_stop_task (GST_PAD (tmp));
    gst_element_remove_pad (GST_ELEMENT (splitmux), GST_PAD (tmp));
  }
  g_list_free (pads_list);
  SPLITMUX_SRC_LOCK (splitmux);

  g_free (splitmux->parts);
  splitmux->parts = NULL;
  splitmux->num_parts = 0;
  splitmux->running = FALSE;
  splitmux->total_duration = GST_CLOCK_TIME_NONE;
  /* Reset playback segment */
  gst_segment_init (&splitmux->play_segment, GST_FORMAT_TIME);
out:
  SPLITMUX_SRC_UNLOCK (splitmux);
  return ret;
}

typedef struct
{
  GstSplitMuxSrc *splitmux;
  SplitMuxSrcPad *splitpad;
} SplitMuxAndPad;

static gboolean
handle_sticky_events (GstPad * pad, GstEvent ** event, gpointer user_data)
{
  SplitMuxAndPad *splitmux_and_pad;
  GstSplitMuxSrc *splitmux;
  SplitMuxSrcPad *splitpad;

  splitmux_and_pad = user_data;
  splitmux = splitmux_and_pad->splitmux;
  splitpad = splitmux_and_pad->splitpad;

  GST_DEBUG_OBJECT (splitpad, "handle sticky event %" GST_PTR_FORMAT, *event);
  gst_event_ref (*event);
  gst_splitmux_handle_event (splitmux, splitpad, pad, *event);

  return TRUE;
}

static GstPad *
gst_splitmux_find_output_pad (GstSplitMuxPartReader * part, GstPad * pad,
    GstSplitMuxSrc * splitmux)
{
  GList *cur;
  gchar *pad_name = gst_pad_get_name (pad);
  GstPad *target = NULL;
  gboolean is_new_pad = FALSE;

  SPLITMUX_SRC_LOCK (splitmux);
  SPLITMUX_SRC_PADS_LOCK (splitmux);
  for (cur = g_list_first (splitmux->pads);
      cur != NULL; cur = g_list_next (cur)) {
    GstPad *tmp = (GstPad *) (cur->data);
    if (g_str_equal (GST_PAD_NAME (tmp), pad_name)) {
      target = tmp;
      break;
    }
  }

  if (target == NULL && !splitmux->pads_complete) {
    SplitMuxAndPad splitmux_and_pad;

    /* No pad found, create one */
    target = g_object_new (SPLITMUX_TYPE_SRC_PAD,
        "name", pad_name, "direction", GST_PAD_SRC, NULL);
    splitmux->pads = g_list_prepend (splitmux->pads, target);

    gst_pad_set_active (target, TRUE);

    splitmux_and_pad.splitmux = splitmux;
    splitmux_and_pad.splitpad = (SplitMuxSrcPad *) target;
    gst_pad_sticky_events_foreach (pad, handle_sticky_events,
        &splitmux_and_pad);
    is_new_pad = TRUE;
  }
  SPLITMUX_SRC_PADS_UNLOCK (splitmux);
  SPLITMUX_SRC_UNLOCK (splitmux);

  g_free (pad_name);

  if (target == NULL)
    goto pad_not_found;

  if (is_new_pad)
    gst_element_add_pad (GST_ELEMENT_CAST (splitmux), target);

  return target;

pad_not_found:
  GST_ELEMENT_ERROR (splitmux, STREAM, FAILED, (NULL),
      ("Stream part %s contains extra unknown pad %" GST_PTR_FORMAT,
          part->path, pad));
  return NULL;
}

static void
gst_splitmux_part_prepared (GstSplitMuxPartReader * reader,
    GstSplitMuxSrc * splitmux)
{
  gboolean need_no_more_pads;

  GST_LOG_OBJECT (splitmux, "Part %" GST_PTR_FORMAT " prepared", reader);
  SPLITMUX_SRC_LOCK (splitmux);
  need_no_more_pads = !splitmux->pads_complete;
  splitmux->pads_complete = TRUE;
  SPLITMUX_SRC_UNLOCK (splitmux);

  if (need_no_more_pads) {
    GST_DEBUG_OBJECT (splitmux, "Signalling no-more-pads");
    gst_element_no_more_pads (GST_ELEMENT_CAST (splitmux));
  }
}

static void
gst_splitmux_push_event (GstSplitMuxSrc * splitmux, GstEvent * e,
    guint32 seqnum)
{
  GList *cur;

  if (seqnum)
    gst_event_set_seqnum (e, seqnum);

  SPLITMUX_SRC_PADS_LOCK (splitmux);
  for (cur = g_list_first (splitmux->pads);
      cur != NULL; cur = g_list_next (cur)) {
    GstPad *pad = GST_PAD_CAST (cur->data);
    gst_event_ref (e);
    gst_pad_push_event (pad, e);
  }
  SPLITMUX_SRC_PADS_UNLOCK (splitmux);

  gst_event_unref (e);
}

static void
gst_splitmux_push_flush_stop (GstSplitMuxSrc * splitmux, guint32 seqnum)
{
  GstEvent *e = gst_event_new_flush_stop (TRUE);
  GList *cur;

  if (seqnum)
    gst_event_set_seqnum (e, seqnum);

  SPLITMUX_SRC_PADS_LOCK (splitmux);
  for (cur = g_list_first (splitmux->pads);
      cur != NULL; cur = g_list_next (cur)) {
    SplitMuxSrcPad *target = (SplitMuxSrcPad *) (cur->data);

    gst_event_ref (e);
    gst_pad_push_event (GST_PAD_CAST (target), e);
    target->sent_caps = FALSE;
    target->sent_stream_start = FALSE;
    target->sent_segment = FALSE;
  }
  SPLITMUX_SRC_PADS_UNLOCK (splitmux);

  gst_event_unref (e);
}

/* Callback for when a part finishes and we need to move to the next */
static gboolean
gst_splitmux_end_of_part (GstSplitMuxSrc * splitmux, SplitMuxSrcPad * splitpad)
{
  gint next_part = -1;
  gint cur_part = splitpad->cur_part;
  gboolean res = FALSE;

  if (splitmux->play_segment.rate >= 0.0) {
    if (cur_part + 1 < splitmux->num_parts)
      next_part = cur_part + 1;
    /* Make sure the transition is seamless */
    splitpad->set_next_discont = FALSE;
    splitpad->clear_next_discont = TRUE;
  } else {
    /* Reverse play - move to previous segment */
    if (cur_part > 0) {
      next_part = cur_part - 1;
      /* Non-seamless transition in reverse */
      splitpad->set_next_discont = TRUE;
      splitpad->clear_next_discont = FALSE;
    }
  }

  SPLITMUX_SRC_LOCK (splitmux);

  /* If all pads are done with this part, deactivate it */
  if (gst_splitmux_part_is_eos (splitmux->parts[splitpad->cur_part]))
    gst_splitmux_part_reader_deactivate (splitmux->parts[cur_part]);

  if (splitmux->play_segment.rate >= 0.0) {
    if (splitmux->play_segment.stop != -1) {
      GstClockTime part_end =
          gst_splitmux_part_reader_get_end_offset (splitmux->parts[cur_part]);
      if (part_end >= splitmux->play_segment.stop) {
        GST_DEBUG_OBJECT (splitmux,
            "Stop position was within that part. Finishing");
        next_part = -1;
      }
    }
  } else {
    if (splitmux->play_segment.start != -1) {
      GstClockTime part_start =
          gst_splitmux_part_reader_get_start_offset (splitmux->parts[cur_part]);
      if (part_start <= splitmux->play_segment.start) {
        GST_DEBUG_OBJECT (splitmux,
            "Start position %" GST_TIME_FORMAT
            " was within that part. Finishing",
            GST_TIME_ARGS (splitmux->play_segment.start));
        next_part = -1;
      }
    }
  }

  if (next_part != -1) {
    GST_DEBUG_OBJECT (splitmux, "At EOS on pad %" GST_PTR_FORMAT
        " moving to part %d", splitpad, next_part);
    splitpad->cur_part = next_part;
    splitpad->reader = splitmux->parts[splitpad->cur_part];
    if (splitpad->part_pad)
      gst_object_unref (splitpad->part_pad);
    splitpad->part_pad =
        gst_splitmux_part_reader_lookup_pad (splitpad->reader,
        (GstPad *) (splitpad));

    if (splitmux->cur_part != next_part) {
      if (!gst_splitmux_part_reader_is_active (splitpad->reader)) {
        GstSegment tmp;
        /* If moving backward into a new part, set stop
         * to -1 to ensure we play the entire file - workaround
         * a bug in qtdemux that misses bits at the end */
        gst_segment_copy_into (&splitmux->play_segment, &tmp);
        if (tmp.rate < 0)
          tmp.stop = -1;

        /* This is the first pad to move to the new part, activate it */
        GST_DEBUG_OBJECT (splitpad,
            "First pad to change part. Activating part %d with seg %"
            GST_SEGMENT_FORMAT, next_part, &tmp);
        if (!gst_splitmux_part_reader_activate (splitpad->reader, &tmp,
                GST_SEEK_FLAG_NONE))
          goto error;
      }
      splitmux->cur_part = next_part;
    }
    res = TRUE;
  }

  SPLITMUX_SRC_UNLOCK (splitmux);
  return res;
error:
  SPLITMUX_SRC_UNLOCK (splitmux);
  GST_ELEMENT_ERROR (splitmux, RESOURCE, READ, (NULL),
      ("Failed to activate part %d", splitmux->cur_part));
  return FALSE;
}

G_DEFINE_TYPE (SplitMuxSrcPad, splitmux_src_pad, GST_TYPE_PAD);

static void
splitmux_src_pad_constructed (GObject * pad)
{
  gst_pad_set_event_function (GST_PAD (pad),
      GST_DEBUG_FUNCPTR (splitmux_src_pad_event));
  gst_pad_set_query_function (GST_PAD (pad),
      GST_DEBUG_FUNCPTR (splitmux_src_pad_query));

  G_OBJECT_CLASS (splitmux_src_pad_parent_class)->constructed (pad);
}

static void
gst_splitmux_src_pad_dispose (GObject * object)
{
  SplitMuxSrcPad *pad = (SplitMuxSrcPad *) (object);

  GST_OBJECT_LOCK (pad);
  if (pad->part_pad) {
    gst_object_unref (pad->part_pad);
    pad->part_pad = NULL;
  }
  GST_OBJECT_UNLOCK (pad);

  G_OBJECT_CLASS (splitmux_src_pad_parent_class)->dispose (object);
}

static void
splitmux_src_pad_class_init (SplitMuxSrcPadClass * klass)
{
  GObjectClass *gobject_klass = (GObjectClass *) (klass);

  gobject_klass->constructed = splitmux_src_pad_constructed;
  gobject_klass->dispose = gst_splitmux_src_pad_dispose;
}

static void
splitmux_src_pad_init (SplitMuxSrcPad * pad)
{
}

/* Event handler for source pads. Proxy events into the child
 * parts as needed
 */
static gboolean
splitmux_src_pad_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstSplitMuxSrc *splitmux = GST_SPLITMUX_SRC (parent);
  gboolean ret = FALSE;

  GST_DEBUG_OBJECT (parent, "event %" GST_PTR_FORMAT
      " on %" GST_PTR_FORMAT, event, pad);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEEK:{
      GstFormat format;
      gdouble rate;
      GstSeekFlags flags;
      GstSeekType start_type, stop_type;
      gint64 start, stop;
      guint32 seqnum;
      gint i;
      GstClockTime part_start, position;
      GList *cur;
      GstSegment tmp;

      gst_event_parse_seek (event, &rate, &format, &flags,
          &start_type, &start, &stop_type, &stop);

      if (format != GST_FORMAT_TIME) {
        GST_DEBUG_OBJECT (splitmux, "can only seek on TIME");
        goto error;
      }
      /* FIXME: Support non-flushing seeks, which might never wake up */
      if (!(flags & GST_SEEK_FLAG_FLUSH)) {
        GST_DEBUG_OBJECT (splitmux, "Only flushing seeks supported");
        goto error;
      }
      seqnum = gst_event_get_seqnum (event);

      SPLITMUX_SRC_LOCK (splitmux);
      if (!splitmux->running || splitmux->num_parts < 1) {
        /* Not started yet */
        SPLITMUX_SRC_UNLOCK (splitmux);
        goto error;
      }

      gst_segment_copy_into (&splitmux->play_segment, &tmp);

      if (!gst_segment_do_seek (&tmp, rate,
              format, flags, start_type, start, stop_type, stop, NULL)) {
        /* Invalid seek requested, ignore it */
        SPLITMUX_SRC_UNLOCK (splitmux);
        goto error;
      }
      position = tmp.position;

      GST_DEBUG_OBJECT (splitmux, "Performing seek with seg %"
          GST_SEGMENT_FORMAT, &tmp);

      GST_DEBUG_OBJECT (splitmux,
          "Handling flushing seek. Sending flush start");

      /* Send flush_start */
      gst_splitmux_push_event (splitmux, gst_event_new_flush_start (), seqnum);

      /* Stop all parts, which will work because of the flush */
      SPLITMUX_SRC_PADS_LOCK (splitmux);
      SPLITMUX_SRC_UNLOCK (splitmux);
      for (cur = g_list_first (splitmux->pads);
          cur != NULL; cur = g_list_next (cur)) {
        SplitMuxSrcPad *target = (SplitMuxSrcPad *) (cur->data);
        GstSplitMuxPartReader *reader = splitmux->parts[target->cur_part];
        gst_splitmux_part_reader_deactivate (reader);
      }

      /* Shut down pad tasks */
      GST_DEBUG_OBJECT (splitmux, "Pausing pad tasks");
      for (cur = g_list_first (splitmux->pads);
          cur != NULL; cur = g_list_next (cur)) {
        GstPad *splitpad = (GstPad *) (cur->data);
        gst_pad_pause_task (GST_PAD (splitpad));
      }
      SPLITMUX_SRC_PADS_UNLOCK (splitmux);
      SPLITMUX_SRC_LOCK (splitmux);

      /* Send flush stop */
      GST_DEBUG_OBJECT (splitmux, "Sending flush stop");
      gst_splitmux_push_flush_stop (splitmux, seqnum);

      /* Everything is stopped, so update the play_segment */
      gst_segment_copy_into (&tmp, &splitmux->play_segment);
      splitmux->segment_seqnum = seqnum;

      /* Work out where to start from now */
      for (i = 0; i < splitmux->num_parts; i++) {
        GstSplitMuxPartReader *reader = splitmux->parts[i];
        GstClockTime part_end =
            gst_splitmux_part_reader_get_end_offset (reader);

        if (part_end > position)
          break;
      }
      if (i == splitmux->num_parts)
        i = splitmux->num_parts - 1;

      part_start =
          gst_splitmux_part_reader_get_start_offset (splitmux->parts[i]);

      GST_DEBUG_OBJECT (splitmux,
          "Seek to time %" GST_TIME_FORMAT " landed in part %d offset %"
          GST_TIME_FORMAT, GST_TIME_ARGS (position),
          i, GST_TIME_ARGS (position - part_start));

      ret = gst_splitmux_src_activate_part (splitmux, i, flags);
      SPLITMUX_SRC_UNLOCK (splitmux);
    }
    default:
      break;
  }

  gst_event_unref (event);
error:
  return ret;
}

static gboolean
splitmux_src_pad_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
  /* Query handler for source pads. Proxy queries into the child
   * parts as needed
   */
  GstSplitMuxSrc *splitmux = GST_SPLITMUX_SRC (parent);
  gboolean ret = FALSE;

  GST_LOG_OBJECT (parent, "query %" GST_PTR_FORMAT
      " on %" GST_PTR_FORMAT, query, pad);
  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_CAPS:
    case GST_QUERY_POSITION:{
      GstSplitMuxPartReader *part;
      SplitMuxSrcPad *anypad;

      SPLITMUX_SRC_LOCK (splitmux);
      SPLITMUX_SRC_PADS_LOCK (splitmux);
      anypad = (SplitMuxSrcPad *) (splitmux->pads->data);
      part = splitmux->parts[anypad->cur_part];
      ret = gst_splitmux_part_reader_src_query (part, pad, query);
      SPLITMUX_SRC_PADS_UNLOCK (splitmux);
      SPLITMUX_SRC_UNLOCK (splitmux);
      break;
    }
    case GST_QUERY_DURATION:{
      GstClockTime duration;
      GstFormat fmt;

      gst_query_parse_duration (query, &fmt, NULL);
      if (fmt != GST_FORMAT_TIME)
        break;

      GST_OBJECT_LOCK (splitmux);
      duration = splitmux->total_duration;
      GST_OBJECT_UNLOCK (splitmux);

      if (duration > 0 && duration != GST_CLOCK_TIME_NONE) {
        gst_query_set_duration (query, GST_FORMAT_TIME, duration);
        ret = TRUE;
      }
      break;
    }
    case GST_QUERY_SEEKING:{
      GstFormat format;

      gst_query_parse_seeking (query, &format, NULL, NULL, NULL);
      if (format != GST_FORMAT_TIME)
        break;

      GST_OBJECT_LOCK (splitmux);
      gst_query_set_seeking (query, GST_FORMAT_TIME, TRUE, 0,
          splitmux->total_duration);
      ret = TRUE;
      GST_OBJECT_UNLOCK (splitmux);

      break;
    }
    default:
      break;
  }
  return ret;
}


gboolean
register_splitmuxsrc (GstPlugin * plugin)
{
  GST_DEBUG_CATEGORY_INIT (splitmux_debug, "splitmuxsrc", 0,
      "Split File Demuxing Source");

  return gst_element_register (plugin, "splitmuxsrc", GST_RANK_NONE,
      GST_TYPE_SPLITMUX_SRC);
}
