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


/**
 * SECTION:gstnonstreamaudiodecoder
 * @short_description: Base class for decoding of non-streaming audio
 * @see_also: #GstAudioDecoder
 *
 * This base class is for decoders which do not operate on a streaming model.
 * That is: they load the encoded media at once, as part of an initialization,
 * and afterwards can decode samples (sometimes referred to as "rendering the
 * samples").
 *
 * This sets it apart from GstAudioDecoder, which is a base class for
 * streaming audio decoders.
 *
 * The base class is conceptually a mix between decoder and parser. This is
 * unavoidable, since virtually no format that isn't streaming based has a
 * clear distinction between parsing and decoding. As a result, this class
 * also handles seeking.
 *
 * Non-streaming audio formats tend to have some characteristics unknown to
 * more "regular" bitstreams. These include subsongs and looping.
 *
 * Subsongs are a set of songs-within-a-song. An analogy would be a multitrack
 * recording, where each track is its own song. The first subsong is typically
 * the "main" one. Subsongs were popular for video games to enable context-
 * aware music; for example, subsong #0 would be the "main" song, #1 would be
 * an alternate song playing when a fight started, #2 would be heard during
 * conversations etc. The base class is designed to always have at least one
 * subsong. If the subclass doesn't provide any, the base class creates a
 * "pseudo" subsong, which is actually the whole song.
 * Downstream is informed about the subsong using a table of contents (TOC),
 * but only if there are at least 2 subsongs.
 *
 * Looping refers to jumps within the song, typically backwards to the loop
 * start (although bi-directional looping is possible). The loop is defined
 * by a chronological start and end; once the playback position reaches the
 * loop end, it jumps back to the loop start.
 * Depending on the subclass, looping may not be possible at all, or it
 * may only be possible to enable/disable it (that is, either no looping, or
 * an infinite amount of loops), or it may allow for defining a finite number
 * of times the loop is repeated.
 * Looping can affect output in two ways. Either, the playback position is
 * reset to the start of the loop, similar to what happens after a seek event.
 * Or, it is not reset, so the pipeline sees playback steadily moving forwards,
 * the playback position monotonically increasing. However, seeking must
 * always happen within the confines of the defined subsong duration; for
 * example, if a subsong is 2 minutes long, steady playback is at 5 minutes
 * (because infinite looping is enabled), then seeking will still place the
 * position within the 2 minute period.
 * Loop count 0 means no looping. Loop count -1 means infinite looping.
 * Nonzero positive values indicate how often a loop shall occur.
 *
 * If the initial subsong and loop count are set to values the subclass does
 * not support, the subclass has a chance to correct these values.
 * @get_property then reports the corrected versions.
 *
 * The base class operates as follows:
 * <orderedlist>
 * <listitem>
 *   <itemizedlist><title>Unloaded mode</title>
 *     <listitem><para>
 *       Initial values are set. If a current subsong has already been
 *       defined (for example over the command line with gst-launch), then
 *       the subsong index is copied over to current_subsong .
 *       Same goes for the num-loops and output-mode properties.
 *       Media is NOT loaded yet.
 *     </para></listitem>
 *     <listitem><para>
 *       Once the sinkpad is activated, the process continues. The sinkpad is
 *       activated in push mode, and the class accumulates the incoming media
 *       data in an adapter inside the sinkpad's chain function until either an
 *       EOS event is received from upstream, or the number of bytes reported
 *       by upstream is reached. Then it loads the media, and starts the decoder
 *       output task.
 *     <listitem><para>
 *       If upstream cannot respond to the size query (in bytes) of @load_from_buffer
 *       fails, an error is reported, and the pipeline stops.
 *     </para></listitem>
 *     <listitem><para>
 *       If there are no errors, @load_from_buffer is called to load the media. The
 *       subclass must at least call gst_nonstream_audio_decoder_set_output_audioinfo()
 *       there, and is free to make use of the initial subsong, output mode, and
 *       position. If the actual output mode or position differs from the initial
 *       value,it must set the initial value to the actual one (for example, if
 *       the actual starting position is always 0, set *initial_position to 0).
 *       If loading is unsuccessful, an error is reported, and the pipeline
 *       stops. Otherwise, the base class calls @get_current_subsong to retrieve
 *       the actual current subsong, @get_subsong_duration to report the current
 *       subsong's duration in a duration event and message, and @get_subsong_tags
 *       to send tags downstream in an event (these functions are optional; if
 *       set to NULL, the associated operation is skipped). Afterwards, the base
 *       class switches to loaded mode, and starts the decoder output task.
 *     </para></listitem>
 *   </itemizedlist>
 *   <itemizedlist><title>Loaded mode</title>
 *     <listitem><para>
 *       Inside the decoder output task, the base class repeatedly calls @decode,
 *       which returns a buffer with decoded, ready-to-play samples. If the
 *       subclass reached the end of playback, @decode returns FALSE, otherwise
 *       TRUE.
 *     </para></listitem>
 *     <listitem><para>
 *       Upon reaching a loop end, subclass either ignores that, or loops back
 *       to the beginning of the loop. In the latter case, if the output mode is set
 *       to LOOPING, the subclass must call gst_nonstream_audio_decoder_handle_loop()
 *       *after* the playback position moved to the start of the loop. In
 *       STEADY mode, the subclass must *not* call this function.
 *       Since many decoders only provide a callback for when the looping occurs,
 *       and that looping occurs inside the decoding operation itself, the following
 *       mechanism for subclass is suggested: set a flag inside such a callback.
 *       Then, in the next @decode call, before doing the decoding, check this flag.
 *       If it is set, gst_nonstream_audio_decoder_handle_loop() is called, and the
 *       flag is cleared.
 *       (This function call is necessary in LOOPING mode because it updates the
 *       current segment and makes sure the next buffer that is sent downstream
 *       has its DISCONT flag set.)
 *     </para></listitem>
 *     <listitem><para>
 *       When the current subsong is switched, @set_current_subsong is called.
 *       If it fails, a warning is reported, and nothing else is done. Otherwise,
 *       it calls @get_subsong_duration to get the new current subsongs's
 *       duration, @get_subsong_tags to get its tags, reports a new duration
 *       (i.e. it sends a duration event downstream and generates a duration
 *       message), updates the current segment, and sends the subsong's tags in
 *       an event downstream. (If @set_current_subsong has been set to NULL by
 *       the subclass, attempts to set a current subsong are ignored; likewise,
 *       if @get_subsong_duration is NULL, no duration is reported, and if
 *       @get_subsong_tags is NULL, no tags are sent downstream.)
 *     </para></listitem>
 *     <listitem><para>
 *       When an attempt is made to switch the output mode, it is checked against
 *       the bitmask returned by @get_supported_output_modes. If the proposed
 *       new output mode is supported, the current segment is updated
 *       (it is open-ended in STEADY mode, and covers the (sub)song length in
 *       LOOPING mode), and the subclass' @set_output_mode function is called
 *       unless it is set to NULL. Subclasses should reset internal loop counters
 *       in this function.
 *     </para></listitem>
 *   </itemizedlist>
 * </listitem>
 * </orderedlist>
 *
 * The relationship between (sub)song duration, output mode, and number of loops
 * is defined this way (this is all done by the base class automatically):
 * <itemizedlist>
 * <listitem><para>
 *   Segments have their duration and stop values set to GST_CLOCK_TIME_NONE in
 *   STEADY mode, and to the duration of the (sub)song in LOOPING mode.
 * </para></listitem>
 * <listitem><para>
 *   The duration that is returned to a DURATION query is always the duration
 *   of the (sub)song, regardless of number of loops or output mode. The same
 *   goes for DURATION messages and tags.
 * </para></listitem>
 * <listitem><para>
 *   If the number of loops is >0 or -1, durations of TOC entries are set to
 *   the duration of the respective subsong in LOOPING mode and to G_MAXINT64 in
 *   STEADY mode. If the number of loops is 0, entry durations are set to the
 *   subsong duration regardless of the output mode.
 * </para></listitem>
 * </itemizedlist>
 */

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

#include <stdio.h>
#include <gst/gst.h>
#include <gst/audio/audio.h>

#include "gstnonstreamaudiodecoder.h"


GST_DEBUG_CATEGORY (nonstream_audiodecoder_debug);
#define GST_CAT_DEFAULT nonstream_audiodecoder_debug


enum
{
  PROP_0,
  PROP_CURRENT_SUBSONG,
  PROP_SUBSONG_MODE,
  PROP_NUM_LOOPS,
  PROP_OUTPUT_MODE
};

#define DEFAULT_CURRENT_SUBSONG 0
#define DEFAULT_SUBSONG_MODE GST_NONSTREAM_AUDIO_SUBSONG_MODE_DECODER_DEFAULT
#define DEFAULT_NUM_SUBSONGS 0
#define DEFAULT_NUM_LOOPS 0
#define DEFAULT_OUTPUT_MODE GST_NONSTREAM_AUDIO_OUTPUT_MODE_STEADY




static GstElementClass *gst_nonstream_audio_decoder_parent_class = NULL;

static void
gst_nonstream_audio_decoder_class_init (GstNonstreamAudioDecoderClass * klass);
static void gst_nonstream_audio_decoder_init (GstNonstreamAudioDecoder * dec,
    GstNonstreamAudioDecoderClass * klass);

static void gst_nonstream_audio_decoder_finalize (GObject * object);
static void gst_nonstream_audio_decoder_set_property (GObject * object,
    guint prop_id, GValue const *value, GParamSpec * pspec);
static void gst_nonstream_audio_decoder_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec);

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

static gboolean gst_nonstream_audio_decoder_sink_event (GstPad * pad,
    GstObject * parent, GstEvent * event);
static gboolean gst_nonstream_audio_decoder_sink_query (GstPad * pad,
    GstObject * parent, GstQuery * query);
static GstFlowReturn gst_nonstream_audio_decoder_chain (GstPad * pad,
    GstObject * parent, GstBuffer * buffer);

static gboolean gst_nonstream_audio_decoder_src_event (GstPad * pad,
    GstObject * parent, GstEvent * event);
static gboolean gst_nonstream_audio_decoder_src_query (GstPad * pad,
    GstObject * parent, GstQuery * query);

static void
gst_nonstream_audio_decoder_set_initial_state (GstNonstreamAudioDecoder * dec);
static void gst_nonstream_audio_decoder_cleanup_state (GstNonstreamAudioDecoder
    * dec);

static gboolean gst_nonstream_audio_decoder_negotiate (GstNonstreamAudioDecoder
    * dec);

static gboolean
gst_nonstream_audio_decoder_negotiate_default (GstNonstreamAudioDecoder * dec);
static gboolean
gst_nonstream_audio_decoder_decide_allocation_default (GstNonstreamAudioDecoder
    * dec, GstQuery * query);
static gboolean
gst_nonstream_audio_decoder_propose_allocation_default (GstNonstreamAudioDecoder
    * dec, GstQuery * query);

static gboolean
gst_nonstream_audio_decoder_get_upstream_size (GstNonstreamAudioDecoder * dec,
    gint64 * length);
static gboolean
gst_nonstream_audio_decoder_load_from_buffer (GstNonstreamAudioDecoder * dec,
    GstBuffer * buffer);
static gboolean
gst_nonstream_audio_decoder_load_from_custom (GstNonstreamAudioDecoder * dec);
static gboolean
gst_nonstream_audio_decoder_finish_load (GstNonstreamAudioDecoder * dec,
    gboolean load_ok, GstClockTime initial_position,
    gboolean send_stream_start);

static gboolean gst_nonstream_audio_decoder_start_task (GstNonstreamAudioDecoder
    * dec);
static gboolean gst_nonstream_audio_decoder_stop_task (GstNonstreamAudioDecoder
    * dec);

static gboolean
gst_nonstream_audio_decoder_switch_to_subsong (GstNonstreamAudioDecoder * dec,
    guint new_subsong, guint32 const *seqnum);

static void gst_nonstream_audio_decoder_update_toc (GstNonstreamAudioDecoder *
    dec, GstNonstreamAudioDecoderClass * klass);
static void
gst_nonstream_audio_decoder_update_subsong_duration (GstNonstreamAudioDecoder *
    dec, GstClockTime duration);
static void
gst_nonstream_audio_decoder_output_new_segment (GstNonstreamAudioDecoder * dec,
    GstClockTime start_position);
static gboolean gst_nonstream_audio_decoder_do_seek (GstNonstreamAudioDecoder *
    dec, GstEvent * event);

static GstTagList
    * gst_nonstream_audio_decoder_add_main_tags (GstNonstreamAudioDecoder * dec,
    GstTagList * tags);

static void gst_nonstream_audio_decoder_output_task (GstNonstreamAudioDecoder *
    dec);

static char const *get_seek_type_name (GstSeekType seek_type);




static GType gst_nonstream_audio_decoder_output_mode_get_type (void);
#define GST_TYPE_NONSTREAM_AUDIO_DECODER_OUTPUT_MODE (gst_nonstream_audio_decoder_output_mode_get_type())

static GType gst_nonstream_audio_decoder_subsong_mode_get_type (void);
#define GST_TYPE_NONSTREAM_AUDIO_DECODER_SUBSONG_MODE (gst_nonstream_audio_decoder_subsong_mode_get_type())


static GType
gst_nonstream_audio_decoder_output_mode_get_type (void)
{
  static GType gst_nonstream_audio_decoder_output_mode_type = 0;

  if (!gst_nonstream_audio_decoder_output_mode_type) {
    static GEnumValue output_mode_values[] = {
      {GST_NONSTREAM_AUDIO_OUTPUT_MODE_LOOPING, "Looping output", "looping"},
      {GST_NONSTREAM_AUDIO_OUTPUT_MODE_STEADY, "Steady output", "steady"},
      {0, NULL, NULL},
    };

    gst_nonstream_audio_decoder_output_mode_type =
        g_enum_register_static ("NonstreamAudioOutputMode", output_mode_values);
  }

  return gst_nonstream_audio_decoder_output_mode_type;
}


static GType
gst_nonstream_audio_decoder_subsong_mode_get_type (void)
{
  static GType gst_nonstream_audio_decoder_subsong_mode_type = 0;

  if (!gst_nonstream_audio_decoder_subsong_mode_type) {
    static GEnumValue subsong_mode_values[] = {
      {GST_NONSTREAM_AUDIO_SUBSONG_MODE_SINGLE, "Play single subsong",
          "single"},
      {GST_NONSTREAM_AUDIO_SUBSONG_MODE_ALL, "Play all subsongs", "all"},
      {GST_NONSTREAM_AUDIO_SUBSONG_MODE_DECODER_DEFAULT,
          "Decoder specific default behavior", "default"},
      {0, NULL, NULL},
    };

    gst_nonstream_audio_decoder_subsong_mode_type =
        g_enum_register_static ("NonstreamAudioSubsongMode",
        subsong_mode_values);
  }

  return gst_nonstream_audio_decoder_subsong_mode_type;
}



/* Manually defining the GType instead of using G_DEFINE_TYPE_WITH_CODE()
 * because the _init() function needs to be able to access the derived
 * class' sink- and srcpads */


GType
gst_nonstream_audio_decoder_get_type (void)
{
  static volatile gsize nonstream_audio_decoder_type = 0;

  if (g_once_init_enter (&nonstream_audio_decoder_type)) {
    GType type_;
    static const GTypeInfo nonstream_audio_decoder_info = {
      sizeof (GstNonstreamAudioDecoderClass),
      NULL,
      NULL,
      (GClassInitFunc) gst_nonstream_audio_decoder_class_init,
      NULL,
      NULL,
      sizeof (GstNonstreamAudioDecoder),
      0,
      (GInstanceInitFunc) gst_nonstream_audio_decoder_init,
      NULL
    };

    type_ = g_type_register_static (GST_TYPE_ELEMENT,
        "GstNonstreamAudioDecoder",
        &nonstream_audio_decoder_info, G_TYPE_FLAG_ABSTRACT);
    g_once_init_leave (&nonstream_audio_decoder_type, type_);
  }

  return nonstream_audio_decoder_type;
}




static void
gst_nonstream_audio_decoder_class_init (GstNonstreamAudioDecoderClass * klass)
{
  GObjectClass *object_class;
  GstElementClass *element_class;

  object_class = G_OBJECT_CLASS (klass);
  element_class = GST_ELEMENT_CLASS (klass);

  gst_nonstream_audio_decoder_parent_class = g_type_class_peek_parent (klass);

  GST_DEBUG_CATEGORY_INIT (nonstream_audiodecoder_debug,
      "nonstreamaudiodecoder", 0, "nonstream audio decoder base class");

  object_class->finalize =
      GST_DEBUG_FUNCPTR (gst_nonstream_audio_decoder_finalize);
  object_class->set_property =
      GST_DEBUG_FUNCPTR (gst_nonstream_audio_decoder_set_property);
  object_class->get_property =
      GST_DEBUG_FUNCPTR (gst_nonstream_audio_decoder_get_property);
  element_class->change_state =
      GST_DEBUG_FUNCPTR (gst_nonstream_audio_decoder_change_state);

  klass->seek = NULL;
  klass->tell = NULL;

  klass->load_from_buffer = NULL;
  klass->load_from_custom = NULL;

  klass->get_main_tags = NULL;

  klass->get_current_subsong = NULL;
  klass->set_current_subsong = NULL;

  klass->get_num_subsongs = NULL;
  klass->get_subsong_duration = NULL;
  klass->get_subsong_tags = NULL;
  klass->set_subsong_mode = NULL;

  klass->set_num_loops = NULL;
  klass->get_num_loops = NULL;

  klass->decode = NULL;

  klass->negotiate =
      GST_DEBUG_FUNCPTR (gst_nonstream_audio_decoder_negotiate_default);

  klass->decide_allocation =
      GST_DEBUG_FUNCPTR (gst_nonstream_audio_decoder_decide_allocation_default);
  klass->propose_allocation =
      GST_DEBUG_FUNCPTR
      (gst_nonstream_audio_decoder_propose_allocation_default);

  klass->loads_from_sinkpad = TRUE;

  g_object_class_install_property (object_class,
      PROP_CURRENT_SUBSONG,
      g_param_spec_uint ("current-subsong",
          "Currently active subsong",
          "Subsong that is currently selected for playback",
          0, G_MAXUINT,
          DEFAULT_CURRENT_SUBSONG, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
      );

  g_object_class_install_property (object_class,
      PROP_SUBSONG_MODE,
      g_param_spec_enum ("subsong-mode",
          "Subsong mode",
          "Mode which defines how to treat subsongs",
          GST_TYPE_NONSTREAM_AUDIO_DECODER_SUBSONG_MODE,
          DEFAULT_SUBSONG_MODE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
      );

  g_object_class_install_property (object_class,
      PROP_NUM_LOOPS,
      g_param_spec_int ("num-loops",
          "Number of playback loops",
          "Number of times a playback loop shall be executed (special values: 0 = no looping; -1 = infinite loop)",
          -1, G_MAXINT,
          DEFAULT_NUM_LOOPS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
      );

  g_object_class_install_property (object_class,
      PROP_OUTPUT_MODE,
      g_param_spec_enum ("output-mode",
          "Output mode",
          "Which mode playback shall use when a loop is encountered; looping = reset position to start of loop, steady = do not reset position",
          GST_TYPE_NONSTREAM_AUDIO_DECODER_OUTPUT_MODE,
          DEFAULT_OUTPUT_MODE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
      );
}


static void
gst_nonstream_audio_decoder_init (GstNonstreamAudioDecoder * dec,
    GstNonstreamAudioDecoderClass * klass)
{
  GstPadTemplate *pad_template;

  /* These are set here, not in gst_nonstream_audio_decoder_set_initial_state(),
   * because these are values for the properties; they are not supposed to be
   * reset in the READY->NULL state change */
  dec->current_subsong = DEFAULT_CURRENT_SUBSONG;
  dec->subsong_mode = DEFAULT_SUBSONG_MODE;
  dec->output_mode = DEFAULT_OUTPUT_MODE;
  dec->num_loops = DEFAULT_NUM_LOOPS;

  /* Calling this here, not in the NULL->READY state change,
   * to make sure get_property calls return valid values */
  gst_nonstream_audio_decoder_set_initial_state (dec);

  dec->input_data_adapter = gst_adapter_new ();
  g_mutex_init (&(dec->mutex));

  {
    /* set up src pad */

    pad_template =
        gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "src");
    g_return_if_fail (pad_template != NULL);    /* derived class is supposed to define a src pad template */

    dec->srcpad = gst_pad_new_from_template (pad_template, "src");
    gst_pad_set_event_function (dec->srcpad,
        GST_DEBUG_FUNCPTR (gst_nonstream_audio_decoder_src_event));
    gst_pad_set_query_function (dec->srcpad,
        GST_DEBUG_FUNCPTR (gst_nonstream_audio_decoder_src_query));
    gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad);
  }

  if (klass->loads_from_sinkpad) {
    /* set up sink pad if this class loads from a sinkpad */

    pad_template =
        gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "sink");
    g_return_if_fail (pad_template != NULL);    /* derived class is supposed to define a sink pad template */

    dec->sinkpad = gst_pad_new_from_template (pad_template, "sink");
    gst_pad_set_event_function (dec->sinkpad,
        GST_DEBUG_FUNCPTR (gst_nonstream_audio_decoder_sink_event));
    gst_pad_set_query_function (dec->sinkpad,
        GST_DEBUG_FUNCPTR (gst_nonstream_audio_decoder_sink_query));
    gst_pad_set_chain_function (dec->sinkpad,
        GST_DEBUG_FUNCPTR (gst_nonstream_audio_decoder_chain));
    gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);
  }
}




static void
gst_nonstream_audio_decoder_finalize (GObject * object)
{
  GstNonstreamAudioDecoder *dec = GST_NONSTREAM_AUDIO_DECODER (object);

  g_mutex_clear (&(dec->mutex));
  g_object_unref (G_OBJECT (dec->input_data_adapter));

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


static void
gst_nonstream_audio_decoder_set_property (GObject * object, guint prop_id,
    GValue const *value, GParamSpec * pspec)
{
  GstNonstreamAudioDecoder *dec = GST_NONSTREAM_AUDIO_DECODER (object);
  GstNonstreamAudioDecoderClass *klass =
      GST_NONSTREAM_AUDIO_DECODER_GET_CLASS (dec);

  switch (prop_id) {
    case PROP_OUTPUT_MODE:
    {
      GstNonstreamAudioOutputMode new_output_mode;
      new_output_mode = g_value_get_enum (value);

      g_assert (klass->get_supported_output_modes);

      if ((klass->get_supported_output_modes (dec) & (1u << new_output_mode)) ==
          0) {
        GST_WARNING_OBJECT (dec,
            "could not set output mode to %s (not supported by subclass)",
            (new_output_mode ==
                GST_NONSTREAM_AUDIO_OUTPUT_MODE_STEADY) ? "steady" : "looping");
        break;
      }

      GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (dec);
      if (new_output_mode != dec->output_mode) {
        gboolean proceed = TRUE;

        if (dec->loaded_mode) {
          GstClockTime cur_position;

          if (klass->set_output_mode != NULL) {
            if (klass->set_output_mode (dec, new_output_mode, &cur_position))
              proceed = TRUE;
            else {
              proceed = FALSE;
              GST_WARNING_OBJECT (dec, "switching to new output mode failed");
            }
          } else {
            GST_DEBUG_OBJECT (dec,
                "cannot call set_output_mode, since it is NULL");
            proceed = FALSE;
          }

          if (proceed) {
            gst_nonstream_audio_decoder_output_new_segment (dec, cur_position);
            dec->output_mode = new_output_mode;
          }
        }

        if (proceed) {
          /* store output mode in case the property is set before the media got loaded */
          dec->output_mode = new_output_mode;
        }
      }
      GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (dec);

      break;
    }

    case PROP_CURRENT_SUBSONG:
    {
      guint new_subsong = g_value_get_uint (value);
      gst_nonstream_audio_decoder_switch_to_subsong (dec, new_subsong, NULL);

      break;
    }

    case PROP_SUBSONG_MODE:
    {
      GstNonstreamAudioSubsongMode new_subsong_mode = g_value_get_enum (value);

      GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (dec);
      if (new_subsong_mode != dec->subsong_mode) {
        gboolean proceed = TRUE;

        if (dec->loaded_mode) {
          GstClockTime cur_position;

          if (klass->set_subsong_mode != NULL) {
            if (klass->set_subsong_mode (dec, new_subsong_mode, &cur_position))
              proceed = TRUE;
            else {
              proceed = FALSE;
              GST_WARNING_OBJECT (dec, "switching to new subsong mode failed");
            }
          } else {
            GST_DEBUG_OBJECT (dec,
                "cannot call set_subsong_mode, since it is NULL");
            proceed = FALSE;
          }

          if (proceed) {
            if (GST_CLOCK_TIME_IS_VALID (cur_position))
              gst_nonstream_audio_decoder_output_new_segment (dec,
                  cur_position);
            dec->subsong_mode = new_subsong_mode;
          }
        }

        if (proceed) {
          /* store subsong mode in case the property is set before the media got loaded */
          dec->subsong_mode = new_subsong_mode;
        }
      }
      GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (dec);

      break;
    }

    case PROP_NUM_LOOPS:
    {
      gint new_num_loops = g_value_get_int (value);

      GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (dec);
      if (new_num_loops != dec->num_loops) {
        if (dec->loaded_mode) {
          if (klass->set_num_loops != NULL) {
            if (!(klass->set_num_loops (dec, new_num_loops)))
              GST_WARNING_OBJECT (dec, "setting number of loops to %u failed",
                  new_num_loops);
          } else
            GST_DEBUG_OBJECT (dec,
                "cannot call set_num_loops, since it is NULL");
        }

        /* store number of loops in case the property is set before the media got loaded */
        dec->num_loops = new_num_loops;
      }
      GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (dec);

      break;
    }

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}


static void
gst_nonstream_audio_decoder_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstNonstreamAudioDecoder *dec = GST_NONSTREAM_AUDIO_DECODER (object);

  switch (prop_id) {
    case PROP_OUTPUT_MODE:
    {
      GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (dec);
      g_value_set_enum (value, dec->output_mode);
      GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (dec);
      break;
    }

    case PROP_CURRENT_SUBSONG:
    {
      GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (dec);
      g_value_set_uint (value, dec->current_subsong);
      GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (dec);
      break;
    }

    case PROP_SUBSONG_MODE:
    {
      GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (dec);
      g_value_set_enum (value, dec->subsong_mode);
      GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (dec);
      break;
    }

    case PROP_NUM_LOOPS:
    {
      GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (dec);
      g_value_set_int (value, dec->num_loops);
      GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (dec);
      break;
    }

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}



static GstStateChangeReturn
gst_nonstream_audio_decoder_change_state (GstElement * element,
    GstStateChange transition)
{
  GstStateChangeReturn ret;

  ret =
      GST_ELEMENT_CLASS (gst_nonstream_audio_decoder_parent_class)->change_state
      (element, transition);
  if (ret == GST_STATE_CHANGE_FAILURE)
    return ret;

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_PAUSED:
    {

      GstNonstreamAudioDecoder *dec = GST_NONSTREAM_AUDIO_DECODER (element);
      GstNonstreamAudioDecoderClass *klass =
          GST_NONSTREAM_AUDIO_DECODER_GET_CLASS (dec);

      /* For decoders that load with some custom method,
       * this is now the time to load
       *
       * It is done *after* calling the parent class' change_state vfunc,
       * since the pad states need to be set up in order for the loading
       * to succeed, since it will try to push a new_caps event
       * downstream etc. (upwards state changes typically are handled
       * *before* calling the parent class' change_state vfunc ; this is
       * a special case) */
      if (!(klass->loads_from_sinkpad) && !(dec->loaded_mode)) {
        gboolean ret;

        /* load_from_custom is required if loads_from_sinkpad is FALSE */
        g_assert (klass->load_from_custom != NULL);

        ret = gst_nonstream_audio_decoder_load_from_custom (dec);

        if (!ret) {
          GST_ERROR_OBJECT (dec, "loading from custom source failed");
          return GST_STATE_CHANGE_FAILURE;
        }

        if (!gst_nonstream_audio_decoder_start_task (dec))
          return GST_STATE_CHANGE_FAILURE;

      }

      break;
    }

    case GST_STATE_CHANGE_PAUSED_TO_READY:
    {
      GstNonstreamAudioDecoder *dec = GST_NONSTREAM_AUDIO_DECODER (element);
      if (!gst_nonstream_audio_decoder_stop_task (dec))
        return GST_STATE_CHANGE_FAILURE;
      break;
    }

    case GST_STATE_CHANGE_READY_TO_NULL:
    {
      GstNonstreamAudioDecoder *dec = GST_NONSTREAM_AUDIO_DECODER (element);

      /* In the READY->NULL state change, reset the decoder to an
       * initial state ensure it can be used for a fresh new session */
      gst_nonstream_audio_decoder_cleanup_state (dec);
      break;
    }

    default:
      break;
  }

  return ret;
}



static gboolean
gst_nonstream_audio_decoder_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event)
{
  gboolean res = FALSE;
  GstNonstreamAudioDecoder *dec = GST_NONSTREAM_AUDIO_DECODER (parent);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEGMENT:
    {
      /* Upstream sends in a byte segment, which is uninteresting here,
       * since a custom segment event is generated anyway */
      gst_event_unref (event);
      res = TRUE;
      break;
    }

    case GST_EVENT_EOS:
    {
      gsize avail_size;
      GstBuffer *adapter_buffer;

      if (dec->loaded_mode) {
        /* If media has already been loaded, then the decoder
         * task has been started; the EOS event can be ignored */

        GST_DEBUG_OBJECT (dec,
            "EOS received after media was loaded -> ignoring");
        res = TRUE;
      } else {
        /* take all data in the input data adapter,
         * and try to load the media from it */

        avail_size = gst_adapter_available (dec->input_data_adapter);
        if (avail_size == 0) {
          GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL),
              ("EOS event raised, but no data was received - cannot load anything"));
          return FALSE;
        }

        adapter_buffer =
            gst_adapter_take_buffer (dec->input_data_adapter, avail_size);

        if (!gst_nonstream_audio_decoder_load_from_buffer (dec, adapter_buffer)) {
          return FALSE;
        }

        res = gst_nonstream_audio_decoder_start_task (dec);
      }

      break;
    }

    default:
      res = gst_pad_event_default (pad, parent, event);
  }

  return res;
}


static gboolean
gst_nonstream_audio_decoder_sink_query (GstPad * pad, GstObject * parent,
    GstQuery * query)
{
  gboolean res = FALSE;
  GstNonstreamAudioDecoder *dec;
  GstNonstreamAudioDecoderClass *klass;

  dec = GST_NONSTREAM_AUDIO_DECODER (parent);
  klass = GST_NONSTREAM_AUDIO_DECODER_GET_CLASS (dec);

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_ALLOCATION:
    {
      if (klass->propose_allocation != NULL)
        res = klass->propose_allocation (dec, query);

      break;
    }

    default:
      res = gst_pad_query_default (pad, parent, query);
  }

  return res;
}


static GstFlowReturn
gst_nonstream_audio_decoder_chain (G_GNUC_UNUSED GstPad * pad,
    GstObject * parent, GstBuffer * buffer)
{
  GstFlowReturn flow_ret = GST_FLOW_OK;
  GstNonstreamAudioDecoder *dec = GST_NONSTREAM_AUDIO_DECODER (parent);

  /* query upstream size in bytes to know how many bytes to expect
   * this is a safety measure to prevent the case when upstream never
   * reaches EOS (or only after a long time) and we keep loading and
   * loading and eventually run out of memory */
  if (dec->upstream_size < 0) {
    if (!gst_nonstream_audio_decoder_get_upstream_size (dec,
            &(dec->upstream_size))) {
      GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL),
          ("Cannot load - upstream size (in bytes) could not be determined"));
      return GST_FLOW_ERROR;
    }
  }

  if (dec->loaded_mode) {
    /* media is already loaded - discard any incoming
     * buffers, since they are not needed */

    GST_DEBUG_OBJECT (dec, "received data after media was loaded - ignoring");

    gst_buffer_unref (buffer);
  } else {
    /* accumulate data until end-of-stream or the upstream
     * size is reached, then load media and commence playback */

    gint64 avail_size;

    gst_adapter_push (dec->input_data_adapter, buffer);
    avail_size = gst_adapter_available (dec->input_data_adapter);
    if (avail_size >= dec->upstream_size) {
      GstBuffer *adapter_buffer =
          gst_adapter_take_buffer (dec->input_data_adapter, avail_size);

      if (gst_nonstream_audio_decoder_load_from_buffer (dec, adapter_buffer))
        flow_ret =
            gst_nonstream_audio_decoder_start_task (dec) ? GST_FLOW_OK :
            GST_FLOW_ERROR;
      else
        flow_ret = GST_FLOW_ERROR;
    }
  }

  return flow_ret;
}



static gboolean
gst_nonstream_audio_decoder_src_event (GstPad * pad, GstObject * parent,
    GstEvent * event)
{
  gboolean res = FALSE;
  GstNonstreamAudioDecoder *dec = GST_NONSTREAM_AUDIO_DECODER (parent);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEEK:
    {
      res = gst_nonstream_audio_decoder_do_seek (dec, event);
      break;
    }

    case GST_EVENT_TOC_SELECT:
    {
      /* NOTE: This event may be received multiple times if it
       * was originally sent to a bin containing multiple sink
       * elements (for example, playbin). This is OK and does
       * not break anything. */

      gchar *uid = NULL;
      guint subsong_idx = 0;
      guint32 seqnum;

      gst_event_parse_toc_select (event, &uid);

      if ((uid != NULL)
          && (sscanf (uid, "nonstream-subsong-%05u", &subsong_idx) == 1)) {
        seqnum = gst_event_get_seqnum (event);

        GST_DEBUG_OBJECT (dec,
            "received TOC select event (sequence number %" G_GUINT32_FORMAT
            "), switching to subsong %u", seqnum, subsong_idx);

        gst_nonstream_audio_decoder_switch_to_subsong (dec, subsong_idx,
            &seqnum);
      }

      g_free (uid);

      res = TRUE;

      break;
    }

    default:
      res = gst_pad_event_default (pad, parent, event);
  }

  return res;
}


static gboolean
gst_nonstream_audio_decoder_src_query (GstPad * pad, GstObject * parent,
    GstQuery * query)
{
  gboolean res = FALSE;
  GstNonstreamAudioDecoder *dec;
  GstNonstreamAudioDecoderClass *klass;

  dec = GST_NONSTREAM_AUDIO_DECODER (parent);
  klass = GST_NONSTREAM_AUDIO_DECODER_GET_CLASS (dec);

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_DURATION:
    {
      GstFormat format;
      GST_TRACE_OBJECT (parent, "duration query");

      if (!(dec->loaded_mode)) {
        GST_DEBUG_OBJECT (parent,
            "cannot respond to duration query: nothing is loaded yet");
        break;
      }

      GST_TRACE_OBJECT (parent, "parsing duration query");
      gst_query_parse_duration (query, &format, NULL);

      GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (dec);
      if ((format == GST_FORMAT_TIME)
          && (dec->subsong_duration != GST_CLOCK_TIME_NONE)) {
        GST_DEBUG_OBJECT (parent,
            "responding to query with duration %" GST_TIME_FORMAT,
            GST_TIME_ARGS (dec->subsong_duration));
        gst_query_set_duration (query, format, dec->subsong_duration);
        res = TRUE;
      } else if (format != GST_FORMAT_TIME)
        GST_DEBUG_OBJECT (parent,
            "cannot respond to duration query: format is %s, expected time format",
            gst_format_get_name (format));
      else if (dec->subsong_duration == GST_CLOCK_TIME_NONE)
        GST_DEBUG_OBJECT (parent,
            "cannot respond to duration query: no valid subsong duration available");
      GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (dec);

      break;
    }

    case GST_QUERY_POSITION:
    {
      GstFormat format;
      if (!(dec->loaded_mode)) {
        GST_DEBUG_OBJECT (parent,
            "cannot respond to position query: nothing is loaded yet");
        break;
      }

      if (klass->tell == NULL) {
        GST_DEBUG_OBJECT (parent,
            "cannot respond to position query: subclass does not have tell() function defined");
        break;
      }

      gst_query_parse_position (query, &format, NULL);
      if (format == GST_FORMAT_TIME) {
        GstClockTime pos;

        GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (dec);
        pos = klass->tell (dec);
        GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (dec);

        GST_DEBUG_OBJECT (parent,
            "position query received with format TIME -> reporting position %"
            GST_TIME_FORMAT, GST_TIME_ARGS (pos));
        gst_query_set_position (query, format, pos);
        res = TRUE;
      } else {
        GST_DEBUG_OBJECT (parent,
            "position query received with unsupported format %s -> not reporting anything",
            gst_format_get_name (format));
      }

      break;
    }

    case GST_QUERY_SEEKING:
    {
      GstFormat fmt;
      GstClockTime duration;

      if (!dec->loaded_mode) {
        GST_DEBUG_OBJECT (parent,
            "cannot respond to seeking query: nothing is loaded yet");
        break;
      }

      if (klass->seek == NULL) {
        GST_DEBUG_OBJECT (parent,
            "cannot respond to seeking query: subclass does not have seek() function defined");
        break;
      }

      gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);

      GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (dec);
      duration = dec->subsong_duration;
      GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (dec);

      if (fmt == GST_FORMAT_TIME) {
        GST_DEBUG_OBJECT (parent,
            "seeking query received with format TIME -> can seek: yes");
        gst_query_set_seeking (query, fmt, TRUE, 0, duration);
        res = TRUE;
      } else {
        GST_DEBUG_OBJECT (parent,
            "seeking query received with unsupported format %s -> can seek: no",
            gst_format_get_name (fmt));
        gst_query_set_seeking (query, fmt, FALSE, 0, -1);
        res = TRUE;
      }

      break;
    }

    default:
      res = gst_pad_query_default (pad, parent, query);
  }

  return res;
}



static void
gst_nonstream_audio_decoder_set_initial_state (GstNonstreamAudioDecoder * dec)
{
  dec->upstream_size = -1;
  dec->loaded_mode = FALSE;

  dec->subsong_duration = GST_CLOCK_TIME_NONE;

  dec->output_format_changed = FALSE;
  gst_audio_info_init (&(dec->output_audio_info));
  dec->num_decoded_samples = 0;
  dec->cur_pos_in_samples = 0;
  gst_segment_init (&(dec->cur_segment), GST_FORMAT_TIME);
  dec->discont = FALSE;

  dec->toc = NULL;

  dec->allocator = NULL;
}


static void
gst_nonstream_audio_decoder_cleanup_state (GstNonstreamAudioDecoder * dec)
{
  gst_adapter_clear (dec->input_data_adapter);

  if (dec->allocator != NULL) {
    gst_object_unref (dec->allocator);
    dec->allocator = NULL;
  }

  if (dec->toc != NULL) {
    gst_toc_unref (dec->toc);
    dec->toc = NULL;
  }

  gst_nonstream_audio_decoder_set_initial_state (dec);
}


static gboolean
gst_nonstream_audio_decoder_negotiate (GstNonstreamAudioDecoder * dec)
{
  /* must be called with lock */

  GstNonstreamAudioDecoderClass *klass;
  gboolean res = TRUE;

  klass = GST_NONSTREAM_AUDIO_DECODER_GET_CLASS (dec);

  /* protected by a mutex, since the allocator might currently be in use */
  if (klass->negotiate != NULL)
    res = klass->negotiate (dec);

  return res;
}


static gboolean
gst_nonstream_audio_decoder_negotiate_default (GstNonstreamAudioDecoder * dec)
{
  /* mutex is locked when this is called */

  GstCaps *caps;
  GstNonstreamAudioDecoderClass *klass;
  gboolean res = TRUE;
  GstQuery *query = NULL;
  GstAllocator *allocator;
  GstAllocationParams allocation_params;

  g_return_val_if_fail (GST_IS_NONSTREAM_AUDIO_DECODER (dec), FALSE);
  g_return_val_if_fail (GST_AUDIO_INFO_IS_VALID (&(dec->output_audio_info)),
      FALSE);

  klass = GST_NONSTREAM_AUDIO_DECODER_CLASS (G_OBJECT_GET_CLASS (dec));

  caps = gst_audio_info_to_caps (&(dec->output_audio_info));

  GST_DEBUG_OBJECT (dec, "setting src caps %" GST_PTR_FORMAT, (gpointer) caps);

  res = gst_pad_push_event (dec->srcpad, gst_event_new_caps (caps));
  /* clear any pending reconfigure flag */
  gst_pad_check_reconfigure (dec->srcpad);

  if (!res) {
    GST_WARNING_OBJECT (dec, "could not push new caps event downstream");
    goto done;
  }

  GST_TRACE_OBJECT (dec, "src caps set");

  dec->output_format_changed = FALSE;

  query = gst_query_new_allocation (caps, TRUE);
  if (!gst_pad_peer_query (dec->srcpad, query)) {
    GST_DEBUG_OBJECT (dec, "didn't get downstream ALLOCATION hints");
  }

  g_assert (klass->decide_allocation != NULL);
  res = klass->decide_allocation (dec, query);

  GST_DEBUG_OBJECT (dec, "ALLOCATION (%d) params: %" GST_PTR_FORMAT, res,
      (gpointer) query);

  if (!res)
    goto no_decide_allocation;

  /* we got configuration from our peer or the decide_allocation method,
   * parse them */
  if (gst_query_get_n_allocation_params (query) > 0) {
    gst_query_parse_nth_allocation_param (query, 0, &allocator,
        &allocation_params);
  } else {
    allocator = NULL;
    gst_allocation_params_init (&allocation_params);
  }

  if (dec->allocator != NULL)
    gst_object_unref (dec->allocator);
  dec->allocator = allocator;
  dec->allocation_params = allocation_params;

done:
  if (query != NULL)
    gst_query_unref (query);
  gst_caps_unref (caps);

  return res;

no_decide_allocation:
  {
    GST_WARNING_OBJECT (dec, "subclass failed to decide allocation");
    goto done;
  }
}


static gboolean
gst_nonstream_audio_decoder_decide_allocation_default (G_GNUC_UNUSED
    GstNonstreamAudioDecoder * dec, GstQuery * query)
{
  GstAllocator *allocator = NULL;
  GstAllocationParams params;
  gboolean update_allocator;

  /* we got configuration from our peer or the decide_allocation method,
   * parse them */
  if (gst_query_get_n_allocation_params (query) > 0) {
    /* try the allocator */
    gst_query_parse_nth_allocation_param (query, 0, &allocator, &params);
    update_allocator = TRUE;
  } else {
    allocator = NULL;
    gst_allocation_params_init (&params);
    update_allocator = FALSE;
  }

  if (update_allocator)
    gst_query_set_nth_allocation_param (query, 0, allocator, &params);
  else
    gst_query_add_allocation_param (query, allocator, &params);

  if (allocator)
    gst_object_unref (allocator);

  return TRUE;
}


static gboolean
gst_nonstream_audio_decoder_propose_allocation_default (G_GNUC_UNUSED
    GstNonstreamAudioDecoder * dec, G_GNUC_UNUSED GstQuery * query)
{
  return TRUE;
}


static gboolean
gst_nonstream_audio_decoder_get_upstream_size (GstNonstreamAudioDecoder * dec,
    gint64 * length)
{
  return gst_pad_peer_query_duration (dec->sinkpad, GST_FORMAT_BYTES, length)
      && (*length >= 0);
}


static gboolean
gst_nonstream_audio_decoder_load_from_buffer (GstNonstreamAudioDecoder * dec,
    GstBuffer * buffer)
{
  gboolean load_ok;
  GstClockTime initial_position;
  GstNonstreamAudioDecoderClass *klass;
  gboolean ret;

  klass = GST_NONSTREAM_AUDIO_DECODER_CLASS (G_OBJECT_GET_CLASS (dec));
  g_assert (klass->load_from_buffer != NULL);

  GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (dec);

  GST_LOG_OBJECT (dec, "read %" G_GSIZE_FORMAT " bytes from upstream",
      gst_buffer_get_size (buffer));

  initial_position = 0;
  load_ok =
      klass->load_from_buffer (dec, buffer, dec->current_subsong,
      dec->subsong_mode, &initial_position, &(dec->output_mode),
      &(dec->num_loops));
  gst_buffer_unref (buffer);

  ret =
      gst_nonstream_audio_decoder_finish_load (dec, load_ok, initial_position,
      FALSE);

  GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (dec);

  return ret;
}


static gboolean
gst_nonstream_audio_decoder_load_from_custom (GstNonstreamAudioDecoder * dec)
{
  gboolean load_ok;
  GstClockTime initial_position;
  GstNonstreamAudioDecoderClass *klass;
  gboolean ret;

  klass = GST_NONSTREAM_AUDIO_DECODER_CLASS (G_OBJECT_GET_CLASS (dec));
  g_assert (klass->load_from_custom != NULL);

  GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (dec);

  GST_LOG_OBJECT (dec,
      "reading song from custom source defined by derived class");

  initial_position = 0;
  load_ok =
      klass->load_from_custom (dec, dec->current_subsong, dec->subsong_mode,
      &initial_position, &(dec->output_mode), &(dec->num_loops));

  ret =
      gst_nonstream_audio_decoder_finish_load (dec, load_ok, initial_position,
      TRUE);

  GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (dec);

  return ret;
}


static gboolean
gst_nonstream_audio_decoder_finish_load (GstNonstreamAudioDecoder * dec,
    gboolean load_ok, GstClockTime initial_position, gboolean send_stream_start)
{
  /* must be called with lock */

  GstNonstreamAudioDecoderClass *klass =
      GST_NONSTREAM_AUDIO_DECODER_CLASS (G_OBJECT_GET_CLASS (dec));

  GST_TRACE_OBJECT (dec, "enter finish_load");


  /* Prerequisites */

  if (!load_ok) {
    GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("Loading failed"));
    return FALSE;
  }

  if (!GST_AUDIO_INFO_IS_VALID (&(dec->output_audio_info))) {
    GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL),
        ("Audio info is invalid after loading"));
    return FALSE;
  }


  /* Log the number of available subsongs */
  if (klass->get_num_subsongs != NULL)
    GST_DEBUG_OBJECT (dec, "%u subsong(s) available",
        klass->get_num_subsongs (dec));


  /* Set the current subsong (or use the default value) */
  if (klass->get_current_subsong != NULL) {
    GST_TRACE_OBJECT (dec, "requesting current subsong");
    dec->current_subsong = klass->get_current_subsong (dec);
  }


  /* Handle the subsong duration */
  if (klass->get_subsong_duration != NULL) {
    GstClockTime duration;
    GST_TRACE_OBJECT (dec, "requesting subsong duration");
    duration = klass->get_subsong_duration (dec, dec->current_subsong);
    gst_nonstream_audio_decoder_update_subsong_duration (dec, duration);
  }


  /* Send tags downstream (if some exist) */
  if (klass->get_subsong_tags != NULL) {
    /* Subsong tags available */

    GstTagList *tags;
    GST_TRACE_OBJECT (dec, "requesting subsong tags");
    tags = klass->get_subsong_tags (dec, dec->current_subsong);
    if (tags != NULL)
      tags = gst_nonstream_audio_decoder_add_main_tags (dec, tags);
    if (tags != NULL)
      gst_pad_push_event (dec->srcpad, gst_event_new_tag (tags));
  } else {
    /* No subsong tags - just send main tags out */

    GstTagList *tags = gst_tag_list_new_empty ();
    tags = gst_nonstream_audio_decoder_add_main_tags (dec, tags);
    gst_pad_push_event (dec->srcpad, gst_event_new_tag (tags));
  }


  /* Send stream start downstream if requested */
  if (send_stream_start) {
    gchar *stream_id;
    GstEvent *event;

    stream_id =
        gst_pad_create_stream_id (dec->srcpad, GST_ELEMENT_CAST (dec), NULL);
    GST_DEBUG_OBJECT (dec, "pushing STREAM_START with stream id \"%s\"",
        stream_id);

    event = gst_event_new_stream_start (stream_id);
    gst_event_set_group_id (event, gst_util_group_id_next ());
    gst_pad_push_event (dec->srcpad, event);
    g_free (stream_id);
  }


  /* Update the table of contents */
  gst_nonstream_audio_decoder_update_toc (dec, klass);


  /* Negotiate output caps and an allocator */
  GST_TRACE_OBJECT (dec, "negotiating caps and allocator");
  if (!gst_nonstream_audio_decoder_negotiate (dec)) {
    GST_ERROR_OBJECT (dec, "negotiation failed - aborting load");
    return FALSE;
  }


  /* Send new segment downstream */
  gst_nonstream_audio_decoder_output_new_segment (dec, initial_position);

  dec->loaded_mode = TRUE;

  GST_TRACE_OBJECT (dec, "exit finish_load");

  return TRUE;
}


static gboolean
gst_nonstream_audio_decoder_start_task (GstNonstreamAudioDecoder * dec)
{
  if (!gst_pad_start_task (dec->srcpad,
          (GstTaskFunction) gst_nonstream_audio_decoder_output_task, dec,
          NULL)) {
    GST_ERROR_OBJECT (dec, "could not start decoder output task");
    return FALSE;
  } else
    return TRUE;
}


static gboolean
gst_nonstream_audio_decoder_stop_task (GstNonstreamAudioDecoder * dec)
{
  if (!gst_pad_stop_task (dec->srcpad)) {
    GST_ERROR_OBJECT (dec, "could not stop decoder output task");
    return FALSE;
  } else
    return TRUE;
}


static gboolean
gst_nonstream_audio_decoder_switch_to_subsong (GstNonstreamAudioDecoder * dec,
    guint new_subsong, guint32 const *seqnum)
{
  gboolean ret = TRUE;
  GstNonstreamAudioDecoderClass *klass =
      GST_NONSTREAM_AUDIO_DECODER_GET_CLASS (dec);


  if (klass->set_current_subsong == NULL) {
    /* If set_current_subsong wasn't set by the subclass, then
     * subsongs are not supported. It is not an error if this
     * function is called in that case, since it might happen
     * because the current-subsong property was set (and since
     * this is a base class property, it is always available). */
    GST_DEBUG_OBJECT (dec, "cannot call set_current_subsong, since it is NULL");
    goto finish;
  }

  if (dec->loaded_mode) {
    GstEvent *fevent;
    GstClockTime new_position;
    GstClockTime new_subsong_duration = GST_CLOCK_TIME_NONE;


    /* Check if (a) new_subsong is already the current subsong
     * and (b) if new_subsong exceeds the number of available
     * subsongs. Do this here, when the song is loaded,
     * because prior to loading, the number of subsong is usually
     * not known (and the loading process might choose a specific
     * subsong to be the current one at the start of playback). */

    GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (dec);

    if (new_subsong == dec->current_subsong) {
      GST_DEBUG_OBJECT (dec,
          "subsong %u is already the current subsong - ignoring call",
          new_subsong);
      goto finish_unlock;
    }

    if (klass->get_num_subsongs) {
      guint num_subsongs = klass->get_num_subsongs (dec);

      if (new_subsong >= num_subsongs) {
        GST_WARNING_OBJECT (dec,
            "subsong %u is out of bounds (there are %u subsongs) - not switching",
            new_subsong, num_subsongs);
        goto finish_unlock;
      }
    }

    GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (dec);


    /* Switching subsongs during playback is very similar to a
     * flushing seek. Therefore, the stream lock must be taken,
     * flush-start/flush-stop events have to be sent, and
     * the pad task has to be restarted. */


    fevent = gst_event_new_flush_start ();
    if (seqnum != NULL) {
      gst_event_set_seqnum (fevent, *seqnum);
      GST_DEBUG_OBJECT (dec,
          "sending flush start event with sequence number %" G_GUINT32_FORMAT,
          *seqnum);
    } else
      GST_DEBUG_OBJECT (dec, "sending flush start event (no sequence number)");

    gst_pad_push_event (dec->srcpad, gst_event_ref (fevent));
    /* unlock upstream pull_range */
    if (klass->loads_from_sinkpad)
      gst_pad_push_event (dec->sinkpad, fevent);
    else
      gst_event_unref (fevent);


    GST_PAD_STREAM_LOCK (dec->srcpad);


    GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (dec);


    if (!(klass->set_current_subsong (dec, new_subsong, &new_position))) {
      /* Switch failed. Do _not_ exit early from here - playback must
       * continue from the current subsong, and it cannot do that if
       * we exit here. Try getting the current position and proceed as
       * if the switch succeeded (but set the return value to FALSE.) */

      ret = FALSE;
      if (klass->tell)
        new_position = klass->tell (dec);
      else
        new_position = 0;
      GST_WARNING_OBJECT (dec, "switching to new subsong %u failed",
          new_subsong);
    }

    /* Flushing seek resets the base time, which means num_decoded_samples
     * needs to be set to 0, since it defines the segment.base value */
    dec->num_decoded_samples = 0;


    fevent = gst_event_new_flush_stop (TRUE);
    if (seqnum != NULL) {
      gst_event_set_seqnum (fevent, *seqnum);
      GST_DEBUG_OBJECT (dec,
          "sending flush stop event with sequence number %" G_GUINT32_FORMAT,
          *seqnum);
    } else
      GST_DEBUG_OBJECT (dec, "sending flush stop event (no sequence number)");

    gst_pad_push_event (dec->srcpad, gst_event_ref (fevent));
    /* unlock upstream pull_range */
    if (klass->loads_from_sinkpad)
      gst_pad_push_event (dec->sinkpad, fevent);
    else
      gst_event_unref (fevent);


    /* use the new subsong's duration (if one exists) */
    if (klass->get_subsong_duration != NULL)
      new_subsong_duration = klass->get_subsong_duration (dec, new_subsong);
    gst_nonstream_audio_decoder_update_subsong_duration (dec,
        new_subsong_duration);

    /* create a new segment for the new subsong */
    gst_nonstream_audio_decoder_output_new_segment (dec, new_position);

    /* use the new subsong's tags (if any exist) */
    if (klass->get_subsong_tags != NULL) {
      GstTagList *subsong_tags = klass->get_subsong_tags (dec, new_subsong);
      if (subsong_tags != NULL)
        subsong_tags =
            gst_nonstream_audio_decoder_add_main_tags (dec, subsong_tags);
      if (subsong_tags != NULL)
        gst_pad_push_event (dec->srcpad, gst_event_new_tag (subsong_tags));
    }

    GST_DEBUG_OBJECT (dec, "successfully switched to new subsong %u",
        new_subsong);
    dec->current_subsong = new_subsong;


    GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (dec);


    /* Subsong has been switched, and all necessary events have been
     * pushed downstream. Restart srcpad task. */
    gst_nonstream_audio_decoder_start_task (dec);

    /* Unlock stream, we are done */
    GST_PAD_STREAM_UNLOCK (dec->srcpad);
  } else {
    /* If song hasn't been loaded yet, then playback cannot currently
     * been happening. In this case, a "switch" is simple - just store
     * the current subsong index. When the song is loaded, it will
     * start playing this subsong. */

    GST_DEBUG_OBJECT (dec,
        "playback hasn't started yet - storing subsong index %u as the current subsong",
        new_subsong);

    GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (dec);
    dec->current_subsong = new_subsong;
    GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (dec);
  }


finish:
  return ret;


finish_unlock:
  GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (dec);
  goto finish;
}


static void
gst_nonstream_audio_decoder_update_toc (GstNonstreamAudioDecoder * dec,
    GstNonstreamAudioDecoderClass * klass)
{
  /* must be called with lock */

  guint num_subsongs, i;

  if (dec->toc != NULL) {
    gst_toc_unref (dec->toc);
    dec->toc = NULL;
  }

  if (klass->get_num_subsongs == NULL)
    return;

  num_subsongs = klass->get_num_subsongs (dec);
  if (num_subsongs <= 1) {
    GST_DEBUG_OBJECT (dec, "no need for a TOC since there is only one subsong");
    return;
  }

  dec->toc = gst_toc_new (GST_TOC_SCOPE_GLOBAL);

  if (klass->get_main_tags) {
    GstTagList *main_tags = klass->get_main_tags (dec);
    if (main_tags)
      gst_toc_set_tags (dec->toc, main_tags);
  }

  for (i = 0; i < num_subsongs; ++i) {
    gchar *uid;
    GstTocEntry *entry;
    GstClockTime duration;
    GstTagList *tags;

    duration =
        (klass->get_subsong_duration !=
        NULL) ? klass->get_subsong_duration (dec, i) : GST_CLOCK_TIME_NONE;
    tags =
        (klass->get_subsong_tags != NULL) ? klass->get_subsong_tags (dec,
        i) : NULL;
    if (!tags)
      tags = gst_tag_list_new_empty ();

    uid = g_strdup_printf ("nonstream-subsong-%05u", i);
    entry = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_TRACK, uid);
    /* Set the UID as title tag for TOC entry if no title already present */
    gst_tag_list_add (tags, GST_TAG_MERGE_KEEP, GST_TAG_TITLE, uid, NULL);
    /* Set the subsong duration as duration tag for TOC entry if no duration already present */
    if (duration != GST_CLOCK_TIME_NONE)
      gst_tag_list_add (tags, GST_TAG_MERGE_KEEP, GST_TAG_DURATION, duration,
          NULL);

    /* FIXME: TOC does not allow GST_CLOCK_TIME_NONE as a stop value */
    if (duration == GST_CLOCK_TIME_NONE)
      duration = G_MAXINT64;

    /* Subsongs always start at 00:00 */
    gst_toc_entry_set_start_stop_times (entry, 0, duration);
    gst_toc_entry_set_tags (entry, tags);

    /* NOTE: *not* adding loop count via gst_toc_entry_set_loop(), since
     * in GstNonstreamAudioDecoder, looping is a playback property, not
     * a property of the subsongs themselves */

    GST_DEBUG_OBJECT (dec,
        "new toc entry: uid: \"%s\" duration: %" GST_TIME_FORMAT " tags: %"
        GST_PTR_FORMAT, uid, GST_TIME_ARGS (duration), (gpointer) tags);

    gst_toc_append_entry (dec->toc, entry);

    g_free (uid);
  }

  gst_pad_push_event (dec->srcpad, gst_event_new_toc (dec->toc, FALSE));
}


static void
gst_nonstream_audio_decoder_update_subsong_duration (GstNonstreamAudioDecoder *
    dec, GstClockTime duration)
{
  /* must be called with lock */

  dec->subsong_duration = duration;
  GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (dec);
  gst_element_post_message (GST_ELEMENT (dec),
      gst_message_new_duration_changed (GST_OBJECT (dec)));
  GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (dec);
}


static void
gst_nonstream_audio_decoder_output_new_segment (GstNonstreamAudioDecoder * dec,
    GstClockTime start_position)
{
  /* must be called with lock */

  GstSegment segment;

  gst_segment_init (&segment, GST_FORMAT_TIME);

  segment.base =
      gst_util_uint64_scale_int (dec->num_decoded_samples, GST_SECOND,
      dec->output_audio_info.rate);
  segment.start = 0;
  segment.time = start_position;
  segment.offset = 0;
  segment.position = 0;

  /* note that num_decoded_samples isn't being reset; it is the
   * analogue to the segment base value, and thus is supposed to
   * monotonically increase, except for when a flushing seek happens
   * (since a flushing seek is supposed to be a fresh restart for
   * the whole pipeline) */
  dec->cur_pos_in_samples = 0;

  /* stop/duration members are not set, on purpose - in case of loops,
   * new segments will be generated, which automatically put an implicit
   * end on the current segment (the segment implicitely "ends" when the
   * new one starts), and having a stop value might cause very slight
   * gaps occasionally due to slight jitter in the calculation of
   * base times etc. */

  GST_DEBUG_OBJECT (dec,
      "output new segment with base %" GST_TIME_FORMAT " time %"
      GST_TIME_FORMAT, GST_TIME_ARGS (segment.base),
      GST_TIME_ARGS (segment.time));

  dec->cur_segment = segment;
  dec->discont = TRUE;

  gst_pad_push_event (dec->srcpad, gst_event_new_segment (&segment));
}


static gboolean
gst_nonstream_audio_decoder_do_seek (GstNonstreamAudioDecoder * dec,
    GstEvent * event)
{
  gboolean res;
  gdouble rate;
  GstFormat format;
  GstSeekFlags flags;
  GstSeekType start_type, stop_type;
  GstClockTime new_position;
  gint64 start, stop;
  GstSegment segment;
  guint32 seqnum;
  gboolean flush;
  GstNonstreamAudioDecoderClass *klass =
      GST_NONSTREAM_AUDIO_DECODER_GET_CLASS (dec);

  if (klass->seek == NULL) {
    GST_DEBUG_OBJECT (dec,
        "cannot seek: subclass does not have seek() function defined");
    return FALSE;
  }

  if (!dec->loaded_mode) {
    GST_DEBUG_OBJECT (dec, "nothing loaded yet - cannot seek");
    return FALSE;
  }

  GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (dec);
  if (!GST_AUDIO_INFO_IS_VALID (&(dec->output_audio_info))) {
    GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (dec);
    GST_DEBUG_OBJECT (dec, "no valid output audioinfo present - cannot seek");
    return FALSE;
  }
  GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (dec);


  GST_DEBUG_OBJECT (dec, "starting seek");

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

  GST_DEBUG_OBJECT (dec,
      "seek event data:  "
      "rate %f  format %s  "
      "start type %s  start %" GST_TIME_FORMAT "  "
      "stop type %s  stop %" GST_TIME_FORMAT,
      rate, gst_format_get_name (format),
      get_seek_type_name (start_type), GST_TIME_ARGS (start),
      get_seek_type_name (stop_type), GST_TIME_ARGS (stop)
      );

  if (format != GST_FORMAT_TIME) {
    GST_DEBUG_OBJECT (dec, "seeking is only supported in TIME format");
    return FALSE;
  }

  if (rate < 0) {
    GST_DEBUG_OBJECT (dec, "only positive seek rates are supported");
    return FALSE;
  }

  flush = ((flags & GST_SEEK_FLAG_FLUSH) == GST_SEEK_FLAG_FLUSH);

  if (flush) {
    GstEvent *fevent = gst_event_new_flush_start ();
    gst_event_set_seqnum (fevent, seqnum);

    GST_DEBUG_OBJECT (dec,
        "sending flush start event with sequence number %" G_GUINT32_FORMAT,
        seqnum);

    gst_pad_push_event (dec->srcpad, gst_event_ref (fevent));
    /* unlock upstream pull_range */
    if (klass->loads_from_sinkpad)
      gst_pad_push_event (dec->sinkpad, fevent);
    else
      gst_event_unref (fevent);
  } else
    gst_pad_pause_task (dec->srcpad);

  GST_PAD_STREAM_LOCK (dec->srcpad);

  segment = dec->cur_segment;

  if (!gst_segment_do_seek (&segment,
          rate, format, flags, start_type, start, stop_type, stop, NULL)) {
    GST_DEBUG_OBJECT (dec, "could not seek in segment");
    GST_PAD_STREAM_UNLOCK (dec->srcpad);
    return FALSE;
  }

  GST_DEBUG_OBJECT (dec,
      "segment data: "
      "seek event data:  "
      "rate %f  applied rate %f  "
      "format %s  "
      "base %" GST_TIME_FORMAT "  "
      "offset %" GST_TIME_FORMAT "  "
      "start %" GST_TIME_FORMAT "  "
      "stop %" GST_TIME_FORMAT "  "
      "time %" GST_TIME_FORMAT "  "
      "position %" GST_TIME_FORMAT "  "
      "duration %" GST_TIME_FORMAT,
      segment.rate, segment.applied_rate,
      gst_format_get_name (segment.format),
      GST_TIME_ARGS (segment.base),
      GST_TIME_ARGS (segment.offset),
      GST_TIME_ARGS (segment.start),
      GST_TIME_ARGS (segment.stop),
      GST_TIME_ARGS (segment.time),
      GST_TIME_ARGS (segment.position), GST_TIME_ARGS (segment.duration)
      );

  GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (dec);

  new_position = segment.position;
  res = klass->seek (dec, &new_position);
  segment.position = new_position;

  dec->cur_segment = segment;
  dec->cur_pos_in_samples =
      gst_util_uint64_scale_int (dec->cur_segment.position,
      dec->output_audio_info.rate, GST_SECOND);
  dec->num_decoded_samples = 0;

  GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (dec);

  if (flush) {
    GstEvent *fevent = gst_event_new_flush_stop (TRUE);
    gst_event_set_seqnum (fevent, seqnum);

    GST_DEBUG_OBJECT (dec,
        "sending flush stop event with sequence number %" G_GUINT32_FORMAT,
        seqnum);

    gst_pad_push_event (dec->srcpad, gst_event_ref (fevent));
    if (klass->loads_from_sinkpad)
      gst_pad_push_event (dec->sinkpad, fevent);
    else
      gst_event_unref (fevent);
  }

  if (res) {
    if (flags & GST_SEEK_FLAG_SEGMENT) {
      GST_DEBUG_OBJECT (dec, "posting SEGMENT_START message");

      gst_element_post_message (GST_ELEMENT (dec),
          gst_message_new_segment_start (GST_OBJECT (dec),
              GST_FORMAT_TIME, segment.start)
          );
    }

    gst_pad_push_event (dec->srcpad, gst_event_new_segment (&segment));

    GST_INFO_OBJECT (dec, "seek succeeded");

    gst_nonstream_audio_decoder_start_task (dec);
  } else {
    GST_WARNING_OBJECT (dec, "seek failed");
  }

  GST_PAD_STREAM_UNLOCK (dec->srcpad);

  gst_event_unref (event);

  return res;
}


static GstTagList *
gst_nonstream_audio_decoder_add_main_tags (GstNonstreamAudioDecoder * dec,
    GstTagList * tags)
{
  GstNonstreamAudioDecoderClass *klass =
      GST_NONSTREAM_AUDIO_DECODER_GET_CLASS (dec);

  if (!klass->get_main_tags)
    return tags;

  tags = gst_tag_list_make_writable (tags);
  if (tags) {
    GstClockTime duration;
    GstTagList *main_tags;

    /* Get main tags. If some exist, merge them with the given tags,
     * and return the merged result. Otherwise, just return the given tags. */
    main_tags = klass->get_main_tags (dec);
    if (main_tags) {
      tags = gst_tag_list_merge (main_tags, tags, GST_TAG_MERGE_REPLACE);
      gst_tag_list_unref (main_tags);
    }

    /* Add subsong duration if available */
    duration = dec->subsong_duration;
    if (GST_CLOCK_TIME_IS_VALID (duration))
      gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_DURATION, duration,
          NULL);

    return tags;
  } else {
    GST_ERROR_OBJECT (dec, "could not make subsong tags writable");
    return NULL;
  }
}


static void
gst_nonstream_audio_decoder_output_task (GstNonstreamAudioDecoder * dec)
{
  GstFlowReturn flow;
  GstBuffer *outbuf;
  guint num_samples;

  GstNonstreamAudioDecoderClass *klass;
  klass = GST_NONSTREAM_AUDIO_DECODER_CLASS (G_OBJECT_GET_CLASS (dec));
  g_assert (klass->decode != NULL);

  GST_NONSTREAM_AUDIO_DECODER_LOCK_MUTEX (dec);

  /* perform the actual decoding */
  if (!(klass->decode (dec, &outbuf, &num_samples))) {
    /* EOS case */
    GST_INFO_OBJECT (dec, "decode() reports end -> sending EOS event");
    gst_pad_push_event (dec->srcpad, gst_event_new_eos ());
    goto pause_unlock;
  }

  if (outbuf == NULL) {
    GST_ERROR_OBJECT (outbuf, "decode() produced NULL buffer");
    goto pause_unlock;
  }

  /* set the buffer's metadata */
  GST_BUFFER_DURATION (outbuf) =
      gst_util_uint64_scale_int (num_samples, GST_SECOND,
      dec->output_audio_info.rate);
  GST_BUFFER_OFFSET (outbuf) = dec->cur_pos_in_samples;
  GST_BUFFER_OFFSET_END (outbuf) = dec->cur_pos_in_samples + num_samples;
  GST_BUFFER_PTS (outbuf) =
      gst_util_uint64_scale_int (dec->cur_pos_in_samples, GST_SECOND,
      dec->output_audio_info.rate);
  GST_BUFFER_DTS (outbuf) = GST_BUFFER_PTS (outbuf);

  if (G_UNLIKELY (dec->discont)) {
    GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
    dec->discont = FALSE;
  }

  GST_LOG_OBJECT (dec,
      "output buffer stats: num_samples = %u  duration = %" GST_TIME_FORMAT
      "  cur_pos_in_samples = %" G_GUINT64_FORMAT "  timestamp = %"
      GST_TIME_FORMAT, num_samples,
      GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)), dec->cur_pos_in_samples,
      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf))
      );

  /* increment sample counters */
  dec->cur_pos_in_samples += num_samples;
  dec->num_decoded_samples += num_samples;

  /* the decode() call might have set a new output format -> renegotiate
   * before sending the new buffer downstream */
  if (G_UNLIKELY (dec->output_format_changed ||
          (GST_AUDIO_INFO_IS_VALID (&(dec->output_audio_info))
              && gst_pad_check_reconfigure (dec->srcpad))
      )) {
    if (!gst_nonstream_audio_decoder_negotiate (dec)) {
      gst_buffer_unref (outbuf);
      GST_LOG_OBJECT (dec, "could not push output buffer: negotiation failed");
      goto pause_unlock;
    }
  }

  GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (dec);

  /* push new samples downstream
   * no need to unref buffer - gst_pad_push() does it in
   * all cases (success and failure) */
  flow = gst_pad_push (dec->srcpad, outbuf);
  switch (flow) {
    case GST_FLOW_OK:
      break;

    case GST_FLOW_FLUSHING:
      GST_LOG_OBJECT (dec, "pipeline is being flushed - pausing task");
      goto pause;

    case GST_FLOW_NOT_NEGOTIATED:
      if (gst_pad_needs_reconfigure (dec->srcpad)) {
        GST_DEBUG_OBJECT (dec, "trying to renegotiate");
        break;
      }
      /* fallthrough to default */

    default:
      GST_ELEMENT_ERROR (dec, STREAM, FAILED, ("Internal data flow error."),
          ("streaming task paused, reason %s (%d)", gst_flow_get_name (flow),
              flow));
  }

  return;

pause:
  GST_INFO_OBJECT (dec, "pausing task");
  /* NOT using stop_task here, since that would cause a deadlock.
   * See the gst_pad_stop_task() documentation for details. */
  gst_pad_pause_task (dec->srcpad);
  return;
pause_unlock:
  GST_NONSTREAM_AUDIO_DECODER_UNLOCK_MUTEX (dec);
  goto pause;
}


static char const *
get_seek_type_name (GstSeekType seek_type)
{
  switch (seek_type) {
    case GST_SEEK_TYPE_NONE:
      return "none";
    case GST_SEEK_TYPE_SET:
      return "set";
    case GST_SEEK_TYPE_END:
      return "end";
    default:
      return "<unknown>";
  }
}




/**
 * gst_nonstream_audio_decoder_handle_loop:
 * @dec: a #GstNonstreamAudioDecoder
 * @new_position New position the next loop starts with
 *
 * Reports that a loop has been completed and creates a new appropriate
 * segment for the next loop.
 *
 * @new_position exists because a loop may not start at the beginning.
 *
 * This function is only useful for subclasses which can be in the
 * GST_NONSTREAM_AUDIO_OUTPUT_MODE_LOOPING output mode, since in the
 * GST_NONSTREAM_AUDIO_OUTPUT_MODE_STEADY output mode, this function
 * does nothing. See #GstNonstreamAudioOutputMode for more details.
 *
 * The subclass calls this during playback when it loops. It produces
 * a new segment with updated base time and internal time values, to allow
 * for seamless looping. It does *not* check the number of elapsed loops;
 * this is up the subclass.
 *
 * Note that if this function is called, then it must be done after the
 * last samples of the loop have been decoded and pushed downstream.
 *
 * This function must be called with the decoder mutex lock held, since it
 * is typically called from within @decode (which in turn are called with
 * the lock already held).
 */
void
gst_nonstream_audio_decoder_handle_loop (GstNonstreamAudioDecoder * dec,
    GstClockTime new_position)
{
  if (dec->output_mode == GST_NONSTREAM_AUDIO_OUTPUT_MODE_STEADY) {
    /* handle_loop makes no sense with open-ended decoders */
    GST_WARNING_OBJECT (dec,
        "ignoring handle_loop() call, since the decoder output mode is \"steady\"");
    return;
  }

  GST_DEBUG_OBJECT (dec,
      "handle_loop() invoked with new_position = %" GST_TIME_FORMAT,
      GST_TIME_ARGS (new_position));

  dec->discont = TRUE;

  gst_nonstream_audio_decoder_output_new_segment (dec, new_position);
}


/**
 * gst_nonstream_audio_decoder_set_output_format:
 * @dec: a #GstNonstreamAudioDecoder
 * @audio_info: Valid audio info structure containing the output format
 *
 * Sets the output caps by means of a GstAudioInfo structure.
 *
 * This must be called latest in the first @decode call, to ensure src caps are
 * set before decoded samples are sent downstream. Typically, this is called
 * from inside @load_from_buffer or @load_from_custom.
 *
 * This function must be called with the decoder mutex lock held, since it
 * is typically called from within the aforementioned vfuncs (which in turn
 * are called with the lock already held).
 *
 * Returns: TRUE if setting the output format succeeded, FALSE otherwise
 */
gboolean
gst_nonstream_audio_decoder_set_output_format (GstNonstreamAudioDecoder * dec,
    GstAudioInfo const *audio_info)
{
  GstCaps *caps;
  GstCaps *templ_caps;
  gboolean caps_ok;
  gboolean res = TRUE;

  g_return_val_if_fail (GST_IS_NONSTREAM_AUDIO_DECODER (dec), FALSE);

  caps = gst_audio_info_to_caps (audio_info);
  if (caps == NULL) {
    GST_WARNING_OBJECT (dec, "Could not create caps out of audio info");
    return FALSE;
  }

  templ_caps = gst_pad_get_pad_template_caps (dec->srcpad);
  caps_ok = gst_caps_is_subset (caps, templ_caps);

  if (caps_ok) {
    dec->output_audio_info = *audio_info;
    dec->output_format_changed = TRUE;

    GST_INFO_OBJECT (dec, "setting output format to %" GST_PTR_FORMAT,
        (gpointer) caps);
  } else {
    GST_WARNING_OBJECT (dec,
        "requested output format %" GST_PTR_FORMAT " does not match template %"
        GST_PTR_FORMAT, (gpointer) caps, (gpointer) templ_caps);

    res = FALSE;
  }

  gst_caps_unref (caps);
  gst_caps_unref (templ_caps);

  return res;
}


/**
 * gst_nonstream_audio_decoder_set_output_format_simple:
 * @dec: a #GstNonstreamAudioDecoder
 * @sample_rate: Output sample rate to use, in Hz
 * @sample_format: Output sample format to use
 * @num_channels: Number of output channels to use
 *
 * Convenience function; sets the output caps by means of common parameters.
 *
 * Internally, this fills a GstAudioInfo structure and calls
 * gst_nonstream_audio_decoder_set_output_format().
 *
 * Returns: TRUE if setting the output format succeeded, FALSE otherwise
 */
gboolean
gst_nonstream_audio_decoder_set_output_format_simple (GstNonstreamAudioDecoder *
    dec, guint sample_rate, GstAudioFormat sample_format, guint num_channels)
{
  GstAudioInfo output_audio_info;

  gst_audio_info_init (&output_audio_info);

  gst_audio_info_set_format (&output_audio_info,
      sample_format, sample_rate, num_channels, NULL);

  return gst_nonstream_audio_decoder_set_output_format (dec,
      &output_audio_info);
}


/**
 * gst_nonstream_audio_decoder_get_downstream_info:
 * @dec: a #GstNonstreamAudioDecoder
 * @format: #GstAudioFormat value to fill with a sample format
 * @sample_rate: Integer to fill with a sample rate
 * @num_channels: Integer to fill with a channel count
 *
 * Gets sample format, sample rate, channel count from the allowed srcpad caps.
 *
 * This is useful for when the subclass wishes to adjust one or more output
 * parameters to whatever downstream is supporting. For example, the output
 * sample rate is often a freely adjustable value in module players.
 *
 * This function tries to find a value inside the srcpad peer's caps for
 * @format, @sample_rate, @num_chnanels . Any of these can be NULL; they
 * (and the corresponding downstream caps) are then skipped while retrieving
 * information. Non-fixated caps are fixated first; the value closest to
 * their present value is then chosen. For example, if the variables pointed
 * to by the arguments are GST_AUDIO_FORMAT_16, 48000 Hz, and 2 channels,
 * and the downstream caps are:
 *
 * "audio/x-raw, format={S16LE,S32LE}, rate=[1,32000], channels=[1,MAX]"
 *
 * Then @format and @channels stay the same, while @sample_rate is set to 32000 Hz.
 * This way, the initial values the the variables pointed to by the arguments
 * are set to can be used as default output values. Note that if no downstream
 * caps can be retrieved, then this function does nothing, therefore it is
 * necessary to ensure that @format, @sample_rate, and @channels have valid
 * initial values.
 *
 * Decoder lock is not held by this function, so it can be called from within
 * any of the class vfuncs.
 */
void
gst_nonstream_audio_decoder_get_downstream_info (GstNonstreamAudioDecoder * dec,
    GstAudioFormat * format, gint * sample_rate, gint * num_channels)
{
  GstCaps *allowed_srccaps;
  guint structure_nr, num_structures;
  gboolean ds_format_found = FALSE, ds_rate_found = FALSE, ds_channels_found =
      FALSE;

  g_return_if_fail (GST_IS_NONSTREAM_AUDIO_DECODER (dec));

  allowed_srccaps = gst_pad_get_allowed_caps (dec->srcpad);
  if (allowed_srccaps == NULL) {
    GST_INFO_OBJECT (dec,
        "no downstream caps available - not modifying arguments");
    return;
  }

  num_structures = gst_caps_get_size (allowed_srccaps);
  GST_DEBUG_OBJECT (dec, "%u structure(s) in downstream caps", num_structures);
  for (structure_nr = 0; structure_nr < num_structures; ++structure_nr) {
    GstStructure *structure;

    ds_format_found = FALSE;
    ds_rate_found = FALSE;
    ds_channels_found = FALSE;

    structure = gst_caps_get_structure (allowed_srccaps, structure_nr);

    /* If all formats which need to be queried are present in the structure,
     * check its contents */
    if (((format == NULL) || gst_structure_has_field (structure, "format")) &&
        ((sample_rate == NULL) || gst_structure_has_field (structure, "rate"))
        && ((num_channels == NULL)
            || gst_structure_has_field (structure, "channels"))) {
      gint fixated_sample_rate;
      gint fixated_num_channels;
      GstAudioFormat fixated_format = 0;
      GstStructure *fixated_str;
      gboolean passed = TRUE;

      /* Make a copy of the structure, since we need to modify
       * (fixate) values inside */
      fixated_str = gst_structure_copy (structure);

      /* Try to fixate and retrieve the sample format */
      if (passed && (format != NULL)) {
        passed = FALSE;

        if ((gst_structure_get_field_type (fixated_str,
                    "format") == G_TYPE_STRING)
            || gst_structure_fixate_field_string (fixated_str, "format",
                gst_audio_format_to_string (*format))) {
          gchar const *fmt_str =
              gst_structure_get_string (fixated_str, "format");
          if (fmt_str
              && ((fixated_format =
                      gst_audio_format_from_string (fmt_str)) !=
                  GST_AUDIO_FORMAT_UNKNOWN)) {
            GST_DEBUG_OBJECT (dec, "found fixated format: %s", fmt_str);
            ds_format_found = TRUE;
            passed = TRUE;
          }
        }
      }

      /* Try to fixate and retrieve the sample rate */
      if (passed && (sample_rate != NULL)) {
        passed = FALSE;

        if ((gst_structure_get_field_type (fixated_str, "rate") == G_TYPE_INT)
            || gst_structure_fixate_field_nearest_int (fixated_str, "rate",
                *sample_rate)) {
          if (gst_structure_get_int (fixated_str, "rate", &fixated_sample_rate)) {
            GST_DEBUG_OBJECT (dec, "found fixated sample rate: %d",
                fixated_sample_rate);
            ds_rate_found = TRUE;
            passed = TRUE;
          }
        }
      }

      /* Try to fixate and retrieve the channel count */
      if (passed && (num_channels != NULL)) {
        passed = FALSE;

        if ((gst_structure_get_field_type (fixated_str,
                    "channels") == G_TYPE_INT)
            || gst_structure_fixate_field_nearest_int (fixated_str, "channels",
                *num_channels)) {
          if (gst_structure_get_int (fixated_str, "channels",
                  &fixated_num_channels)) {
            GST_DEBUG_OBJECT (dec, "found fixated channel count: %d",
                fixated_num_channels);
            ds_channels_found = TRUE;
            passed = TRUE;
          }
        }
      }

      gst_structure_free (fixated_str);

      if (ds_format_found && ds_rate_found && ds_channels_found) {
        *format = fixated_format;
        *sample_rate = fixated_sample_rate;
        *num_channels = fixated_num_channels;
        break;
      }
    }
  }

  gst_caps_unref (allowed_srccaps);

  if ((format != NULL) && !ds_format_found)
    GST_INFO_OBJECT (dec,
        "downstream did not specify format - using default (%s)",
        gst_audio_format_to_string (*format));
  if ((sample_rate != NULL) && !ds_rate_found)
    GST_INFO_OBJECT (dec,
        "downstream did not specify sample rate - using default (%d Hz)",
        *sample_rate);
  if ((num_channels != NULL) && !ds_channels_found)
    GST_INFO_OBJECT (dec,
        "downstream did not specify number of channels - using default (%d channels)",
        *num_channels);
}


/**
 * gst_nonstream_audio_decoder_allocate_output_buffer:
 * @dec: Decoder instance
 * @size: Size of the output buffer, in bytes
 *
 * Allocates an output buffer with the internally configured buffer pool.
 *
 * This function may only be called from within @load_from_buffer,
 * @load_from_custom, and @decode.
 *
 * Returns: Newly allocated output buffer, or NULL if allocation failed
 */
GstBuffer *
gst_nonstream_audio_decoder_allocate_output_buffer (GstNonstreamAudioDecoder *
    dec, gsize size)
{
  if (G_UNLIKELY (dec->output_format_changed ||
          (GST_AUDIO_INFO_IS_VALID (&(dec->output_audio_info))
              && gst_pad_check_reconfigure (dec->srcpad))
      )) {
    /* renegotiate if necessary, before allocating,
     * to make sure the right allocator and the right allocation
     * params are used */
    if (!gst_nonstream_audio_decoder_negotiate (dec)) {
      GST_ERROR_OBJECT (dec,
          "could not allocate output buffer because negotation failed");
      return NULL;
    }
  }

  return gst_buffer_new_allocate (dec->allocator, size,
      &(dec->allocation_params));
}
