/* GStreamer Audio CD Source Base Class
 * Copyright (C) 2005 Tim-Philipp Müller <tim centricular net>
 *
 * 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.
 */

/* TODO:
 *
 *  - in ::start(), we want to post a tags message with an array or a list
 *    of tagslists of all tracks, so that applications know at least the
 *    number of tracks and all track durations immediately without having
 *    to do any querying. We have to decide what type and name to use for
 *    this array of track taglists.
 *
 *  - FIX cddb discid calculation algorithm for mixed mode CDs - do we use
 *    offsets and duration of ALL tracks (data + audio) for the CDDB ID
 *    calculation, or only audio tracks?
 *
 *  - Do we really need properties for the TOC bias/offset stuff? Wouldn't
 *    environment variables make much more sense? Do we need this at all
 *    (does it only affect ancient hardware?)
 */

/**
 * SECTION:gstaudiocdsrc
 * @title: GstAudioCdSrc
 * @short_description: Base class for Audio CD sources
 *
 * Provides a base class for CD digital audio (CDDA) sources, which handles
 * things like seeking, querying, discid calculation, tags, and buffer
 * timestamping.
 *
 * ## Using GstAudioCdSrc-based elements in applications
 *
 * GstAudioCdSrc registers two #GstFormat<!-- -->s of its own, namely
 * the "track" format and the "sector" format. Applications will usually
 * only find the "track" format interesting. You can retrieve that #GstFormat
 * for use in seek events or queries with gst_format_get_by_nick("track").
 *
 * In order to query the number of tracks, for example, an application would
 * set the CDDA source element to READY or PAUSED state and then query the
 * the number of tracks via gst_element_query_duration() using the track
 * format acquired above. Applications can query the currently playing track
 * in the same way.
 *
 * Alternatively, applications may retrieve the currently playing track and
 * the total number of tracks from the taglist that will posted on the bus
 * whenever the CD is opened or the currently playing track changes. The
 * taglist will contain GST_TAG_TRACK_NUMBER and GST_TAG_TRACK_COUNT tags.
 *
 * Applications playing back CD audio using playbin and cdda://n URIs should
 * issue a seek command in track format to change between tracks, rather than
 * setting a new cdda://n+1 URI on playbin (as setting a new URI on playbin
 * involves closing and re-opening the CD device, which is much much slower).
 *
 * ## Tags and meta-information
 *
 * CDDA sources will automatically emit a number of tags, details about which
 * can be found in the libgsttag documentation. Those tags are:
 * #GST_TAG_CDDA_CDDB_DISCID, #GST_TAG_CDDA_CDDB_DISCID_FULL,
 * #GST_TAG_CDDA_MUSICBRAINZ_DISCID, #GST_TAG_CDDA_MUSICBRAINZ_DISCID_FULL,
 * among others.
 *
 * ## Tracks and Table of Contents (TOC)
 *
 * Applications will be informed of the available tracks via a TOC message
 * on the pipeline's #GstBus. The #GstToc will contain a #GstTocEntry for
 * each track, with information about each track. The duration for each
 * track can be retrieved via the #GST_TAG_DURATION tag from each entry's
 * tag list, or calculated via gst_toc_entry_get_start_stop_times().
 * The track entries in the TOC will be sorted by track number.
 *
 */

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

#include <string.h>
#include <stdlib.h>             /* for strtol */
#include <stdio.h>

#include <gst/tag/tag.h>
#include <gst/audio/audio.h>
#include "gstaudiocdsrc.h"
#include "gst/gst-i18n-plugin.h"

GST_DEBUG_CATEGORY_STATIC (gst_audio_cd_src_debug);
#define GST_CAT_DEFAULT gst_audio_cd_src_debug

#define DEFAULT_DEVICE                       "/dev/cdrom"

#define CD_FRAMESIZE_RAW                     (2352)

#define SECTORS_PER_SECOND                   (75)
#define SECTORS_PER_MINUTE                   (75*60)
#define SAMPLES_PER_SECTOR                   (CD_FRAMESIZE_RAW >> 2)
#define TIME_INTERVAL_FROM_SECTORS(sectors)  ((SAMPLES_PER_SECTOR * sectors * GST_SECOND) / 44100)
#define SECTORS_FROM_TIME_INTERVAL(dtime)    (dtime * 44100 / (SAMPLES_PER_SECTOR * GST_SECOND))

enum
{
  ARG_0,
  ARG_MODE,
  ARG_DEVICE,
  ARG_TRACK,
  ARG_TOC_OFFSET,
  ARG_TOC_BIAS
};

struct _GstAudioCdSrcPrivate
{
  GstAudioCdSrcMode mode;

  gchar *device;

  guint num_tracks;
  guint num_all_tracks;
  GstAudioCdSrcTrack *tracks;

  gint cur_track;               /* current track (starting from 0) */
  gint prev_track;              /* current track last time         */
  gint cur_sector;              /* current sector                  */
  gint seek_sector;             /* -1 or sector to seek to         */

  gint uri_track;
  gchar *uri;

  guint32 discid;               /* cddb disc id (for unit test)    */
  gchar mb_discid[32];          /* musicbrainz discid              */

#if 0
  GstIndex *index;
  gint index_id;
#endif

  gint toc_offset;
  gboolean toc_bias;

  GstEvent *toc_event;          /* pending TOC event */
  GstToc *toc;
};

static void gst_audio_cd_src_uri_handler_init (gpointer g_iface,
    gpointer iface_data);
static void gst_audio_cd_src_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static void gst_audio_cd_src_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_audio_cd_src_finalize (GObject * obj);
static gboolean gst_audio_cd_src_query (GstBaseSrc * src, GstQuery * query);
static gboolean gst_audio_cd_src_handle_event (GstBaseSrc * basesrc,
    GstEvent * event);
static gboolean gst_audio_cd_src_do_seek (GstBaseSrc * basesrc,
    GstSegment * segment);
static gboolean gst_audio_cd_src_start (GstBaseSrc * basesrc);
static gboolean gst_audio_cd_src_stop (GstBaseSrc * basesrc);
static GstFlowReturn gst_audio_cd_src_create (GstPushSrc * pushsrc,
    GstBuffer ** buf);
static gboolean gst_audio_cd_src_is_seekable (GstBaseSrc * basesrc);
static void gst_audio_cd_src_update_duration (GstAudioCdSrc * src);
#if 0
static void gst_audio_cd_src_set_index (GstElement * src, GstIndex * index);
static GstIndex *gst_audio_cd_src_get_index (GstElement * src);
#endif

#define gst_audio_cd_src_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstAudioCdSrc, gst_audio_cd_src, GST_TYPE_PUSH_SRC,
    G_IMPLEMENT_INTERFACE (GST_TYPE_URI_HANDLER,
        gst_audio_cd_src_uri_handler_init));

#define SRC_CAPS \
  "audio/x-raw, "               \
  "format = (string) " GST_AUDIO_NE(S16) ", " \
  "layout = (string) interleaved, " \
  "rate = (int) 44100, "            \
  "channels = (int) 2"              \

static GstStaticPadTemplate gst_audio_cd_src_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (SRC_CAPS)
    );

/* our two formats */
static GstFormat track_format;
static GstFormat sector_format;

static void
gst_audio_cd_src_class_init (GstAudioCdSrcClass * klass)
{
  GstElementClass *element_class;
  GstPushSrcClass *pushsrc_class;
  GstBaseSrcClass *basesrc_class;
  GObjectClass *gobject_class;

  gobject_class = (GObjectClass *) klass;
  element_class = (GstElementClass *) klass;
  basesrc_class = (GstBaseSrcClass *) klass;
  pushsrc_class = (GstPushSrcClass *) klass;

  GST_DEBUG_CATEGORY_INIT (gst_audio_cd_src_debug, "audiocdsrc", 0,
      "Audio CD source base class");

  g_type_class_add_private (klass, sizeof (GstAudioCdSrcPrivate));

  /* our very own formats */
  track_format = gst_format_register ("track", "CD track");
  sector_format = gst_format_register ("sector", "CD sector");

  /* register CDDA tags */
  gst_tag_register_musicbrainz_tags ();

#if 0
  ///// FIXME: what type to use here? ///////
  gst_tag_register (GST_TAG_CDDA_TRACK_TAGS, GST_TAG_FLAG_META, GST_TYPE_TAG_LIST, "track-tags", "CDDA taglist for one track", gst_tag_merge_use_first);        ///////////// FIXME: right function??? ///////
#endif

  gobject_class->set_property = gst_audio_cd_src_set_property;
  gobject_class->get_property = gst_audio_cd_src_get_property;
  gobject_class->finalize = gst_audio_cd_src_finalize;

  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DEVICE,
      g_param_spec_string ("device", "Device", "CD device location",
          NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MODE,
      g_param_spec_enum ("mode", "Mode", "Mode", GST_TYPE_AUDIO_CD_SRC_MODE,
          GST_AUDIO_CD_SRC_MODE_NORMAL,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_TRACK,
      g_param_spec_uint ("track", "Track", "Track", 1, 99, 1,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

#if 0
  /* Do we really need this toc adjustment stuff as properties? does the user
   * have a chance to set it in practice, e.g. when using sound-juicer, rb,
   * totem, whatever? Shouldn't we rather use environment variables
   * for this? (tpm) */

  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_TOC_OFFSET,
      g_param_spec_int ("toc-offset", "Table of contents offset",
          "Add <n> sectors to the values reported", G_MININT, G_MAXINT, 0,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_TOC_BIAS,
      g_param_spec_boolean ("toc-bias", "Table of contents bias",
          "Assume that the beginning offset of track 1 as reported in the TOC "
          "will be addressed as LBA 0.  Necessary for some Toshiba drives to "
          "get track boundaries", FALSE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
#endif

  gst_element_class_add_static_pad_template (element_class,
      &gst_audio_cd_src_src_template);

#if 0
  element_class->set_index = GST_DEBUG_FUNCPTR (gst_audio_cd_src_set_index);
  element_class->get_index = GST_DEBUG_FUNCPTR (gst_audio_cd_src_get_index);
#endif

  basesrc_class->start = GST_DEBUG_FUNCPTR (gst_audio_cd_src_start);
  basesrc_class->stop = GST_DEBUG_FUNCPTR (gst_audio_cd_src_stop);
  basesrc_class->query = GST_DEBUG_FUNCPTR (gst_audio_cd_src_query);
  basesrc_class->event = GST_DEBUG_FUNCPTR (gst_audio_cd_src_handle_event);
  basesrc_class->do_seek = GST_DEBUG_FUNCPTR (gst_audio_cd_src_do_seek);
  basesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_audio_cd_src_is_seekable);

  pushsrc_class->create = GST_DEBUG_FUNCPTR (gst_audio_cd_src_create);
}

static void
gst_audio_cd_src_init (GstAudioCdSrc * src)
{
  src->priv =
      G_TYPE_INSTANCE_GET_PRIVATE (src, GST_TYPE_AUDIO_CD_SRC,
      GstAudioCdSrcPrivate);

  /* we're not live and we operate in time */
  gst_base_src_set_format (GST_BASE_SRC (src), GST_FORMAT_TIME);
  gst_base_src_set_live (GST_BASE_SRC (src), FALSE);

  GST_OBJECT_FLAG_SET (src, GST_ELEMENT_FLAG_INDEXABLE);

  src->priv->device = NULL;
  src->priv->mode = GST_AUDIO_CD_SRC_MODE_NORMAL;
  src->priv->uri_track = -1;
}

static void
gst_audio_cd_src_finalize (GObject * obj)
{
  GstAudioCdSrc *cddasrc = GST_AUDIO_CD_SRC (obj);

  g_free (cddasrc->priv->uri);
  g_free (cddasrc->priv->device);

#if 0
  if (cddasrc->priv->index)
    gst_object_unref (cddasrc->priv->index);
#endif

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

static void
gst_audio_cd_src_set_device (GstAudioCdSrc * src, const gchar * device)
{
  if (src->priv->device)
    g_free (src->priv->device);
  src->priv->device = NULL;

  if (!device)
    return;

  /* skip multiple slashes */
  while (*device == '/' && *(device + 1) == '/')
    device++;

#ifdef __sun
  /*
   * On Solaris, /dev/rdsk is used for accessing the CD device, but some
   * applications pass in /dev/dsk, so correct.
   */
  if (strncmp (device, "/dev/dsk", 8) == 0) {
    gchar *rdsk_value;
    rdsk_value = g_strdup_printf ("/dev/rdsk%s", device + 8);
    src->priv->device = g_strdup (rdsk_value);
    g_free (rdsk_value);
  } else {
#endif
    src->priv->device = g_strdup (device);
#ifdef __sun
  }
#endif
}

static void
gst_audio_cd_src_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstAudioCdSrc *src = GST_AUDIO_CD_SRC (object);

  GST_OBJECT_LOCK (src);

  switch (prop_id) {
    case ARG_MODE:{
      src->priv->mode = g_value_get_enum (value);
      break;
    }
    case ARG_DEVICE:{
      const gchar *dev = g_value_get_string (value);

      gst_audio_cd_src_set_device (src, dev);
      break;
    }
    case ARG_TRACK:{
      guint track = g_value_get_uint (value);

      if (src->priv->num_tracks > 0 && track > src->priv->num_tracks) {
        g_warning ("Invalid track %u", track);
      } else if (track > 0 && src->priv->tracks != NULL) {
        src->priv->cur_sector = src->priv->tracks[track - 1].start;
        src->priv->uri_track = track;
      } else {
        src->priv->uri_track = track;   /* seek will be done in start() */
      }
      break;
    }
    case ARG_TOC_OFFSET:{
      src->priv->toc_offset = g_value_get_int (value);
      break;
    }
    case ARG_TOC_BIAS:{
      src->priv->toc_bias = g_value_get_boolean (value);
      break;
    }
    default:{
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
  }

  GST_OBJECT_UNLOCK (src);
}

static void
gst_audio_cd_src_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
#if 0
  GstAudioCdSrcClass *klass = GST_AUDIO_CD_SRC_GET_CLASS (object);
#endif
  GstAudioCdSrc *src = GST_AUDIO_CD_SRC (object);

  GST_OBJECT_LOCK (src);

  switch (prop_id) {
    case ARG_MODE:
      g_value_set_enum (value, src->priv->mode);
      break;
    case ARG_DEVICE:{
#if 0
      if (src->priv->device == NULL && klass->get_default_device != NULL) {
        gchar *d = klass->get_default_device (src);

        if (d != NULL) {
          g_value_set_string (value, DEFAULT_DEVICE);
          g_free (d);
          break;
        }
      }
#endif
      if (src->priv->device == NULL)
        g_value_set_string (value, DEFAULT_DEVICE);
      else
        g_value_set_string (value, src->priv->device);
      break;
    }
    case ARG_TRACK:{
      if (src->priv->num_tracks <= 0 && src->priv->uri_track > 0) {
        g_value_set_uint (value, src->priv->uri_track);
      } else {
        g_value_set_uint (value, src->priv->cur_track + 1);
      }
      break;
    }
    case ARG_TOC_OFFSET:
      g_value_set_int (value, src->priv->toc_offset);
      break;
    case ARG_TOC_BIAS:
      g_value_set_boolean (value, src->priv->toc_bias);
      break;
    default:{
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
  }

  GST_OBJECT_UNLOCK (src);
}

static gint
gst_audio_cd_src_get_track_from_sector (GstAudioCdSrc * src, gint sector)
{
  gint i;

  for (i = 0; i < src->priv->num_tracks; ++i) {
    if (sector >= src->priv->tracks[i].start
        && sector <= src->priv->tracks[i].end)
      return i;
  }
  return -1;
}

static gboolean
gst_audio_cd_src_convert (GstAudioCdSrc * src, GstFormat src_format,
    gint64 src_val, GstFormat dest_format, gint64 * dest_val)
{
  gboolean started;

  GST_LOG_OBJECT (src, "converting value %" G_GINT64_FORMAT " from %s into %s",
      src_val, gst_format_get_name (src_format),
      gst_format_get_name (dest_format));

  if (src_format == dest_format) {
    *dest_val = src_val;
    return TRUE;
  }

  started =
      GST_OBJECT_FLAG_IS_SET (GST_BASE_SRC (src), GST_BASE_SRC_FLAG_STARTED);

  if (src_format == track_format) {
    if (!started)
      goto not_started;
    if (src_val < 0 || src_val >= src->priv->num_tracks) {
      GST_DEBUG_OBJECT (src, "track number %d out of bounds", (gint) src_val);
      goto wrong_value;
    }
    src_format = GST_FORMAT_DEFAULT;
    src_val = src->priv->tracks[src_val].start * (gint64) SAMPLES_PER_SECTOR;
  } else if (src_format == sector_format) {
    src_format = GST_FORMAT_DEFAULT;
    src_val = src_val * SAMPLES_PER_SECTOR;
  }

  if (src_format == dest_format) {
    *dest_val = src_val;
    goto done;
  }

  switch (src_format) {
    case GST_FORMAT_BYTES:
      /* convert to samples (4 bytes per sample) */
      src_val = src_val >> 2;
      /* fallthrough */
    case GST_FORMAT_DEFAULT:{
      switch (dest_format) {
        case GST_FORMAT_BYTES:{
          if (src_val < 0) {
            GST_DEBUG_OBJECT (src, "sample source value negative");
            goto wrong_value;
          }
          *dest_val = src_val << 2;     /* 4 bytes per sample */
          break;
        }
        case GST_FORMAT_TIME:{
          *dest_val = gst_util_uint64_scale_int (src_val, GST_SECOND, 44100);
          break;
        }
        default:{
          gint64 sector = src_val / SAMPLES_PER_SECTOR;

          if (dest_format == sector_format) {
            *dest_val = sector;
          } else if (dest_format == track_format) {
            if (!started)
              goto not_started;
            *dest_val = gst_audio_cd_src_get_track_from_sector (src, sector);
          } else {
            goto unknown_format;
          }
          break;
        }
      }
      break;
    }
    case GST_FORMAT_TIME:{
      gint64 sample_offset;

      if (src_val == GST_CLOCK_TIME_NONE) {
        GST_DEBUG_OBJECT (src, "source time value invalid");
        goto wrong_value;
      }

      sample_offset = gst_util_uint64_scale_int (src_val, 44100, GST_SECOND);
      switch (dest_format) {
        case GST_FORMAT_BYTES:{
          *dest_val = sample_offset << 2;       /* 4 bytes per sample */
          break;
        }
        case GST_FORMAT_DEFAULT:{
          *dest_val = sample_offset;
          break;
        }
        default:{
          gint64 sector = sample_offset / SAMPLES_PER_SECTOR;

          if (dest_format == sector_format) {
            *dest_val = sector;
          } else if (dest_format == track_format) {
            if (!started)
              goto not_started;
            *dest_val = gst_audio_cd_src_get_track_from_sector (src, sector);
          } else {
            goto unknown_format;
          }
          break;
        }
      }
      break;
    }
    default:{
      goto unknown_format;
    }
  }

done:
  {
    GST_LOG_OBJECT (src, "returning %" G_GINT64_FORMAT, *dest_val);
    return TRUE;
  }

unknown_format:
  {
    GST_DEBUG_OBJECT (src, "conversion failed: %s", "unsupported format");
    return FALSE;
  }

wrong_value:
  {
    GST_DEBUG_OBJECT (src, "conversion failed: %s",
        "source value not within allowed range");
    return FALSE;
  }

not_started:
  {
    GST_DEBUG_OBJECT (src, "conversion failed: %s",
        "cannot do this conversion, device not open");
    return FALSE;
  }
}

static gboolean
gst_audio_cd_src_query (GstBaseSrc * basesrc, GstQuery * query)
{
  GstAudioCdSrc *src = GST_AUDIO_CD_SRC (basesrc);
  gboolean started;

  started = GST_OBJECT_FLAG_IS_SET (basesrc, GST_BASE_SRC_FLAG_STARTED);

  GST_LOG_OBJECT (src, "handling %s query",
      gst_query_type_get_name (GST_QUERY_TYPE (query)));

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_DURATION:{
      GstFormat dest_format;
      gint64 dest_val;
      guint sectors;

      gst_query_parse_duration (query, &dest_format, NULL);

      if (!started)
        return FALSE;

      g_assert (src->priv->tracks != NULL);

      if (dest_format == track_format) {
        GST_LOG_OBJECT (src, "duration: %d tracks", src->priv->num_tracks);
        gst_query_set_duration (query, track_format, src->priv->num_tracks);
        return TRUE;
      }

      if (src->priv->cur_track < 0
          || src->priv->cur_track >= src->priv->num_tracks)
        return FALSE;

      if (src->priv->mode == GST_AUDIO_CD_SRC_MODE_NORMAL) {
        sectors = src->priv->tracks[src->priv->cur_track].end -
            src->priv->tracks[src->priv->cur_track].start + 1;
      } else {
        sectors = src->priv->tracks[src->priv->num_tracks - 1].end -
            src->priv->tracks[0].start + 1;
      }

      /* ... and convert into final format */
      if (!gst_audio_cd_src_convert (src, sector_format, sectors,
              dest_format, &dest_val)) {
        return FALSE;
      }

      gst_query_set_duration (query, dest_format, dest_val);

      GST_LOG ("duration: %u sectors, %" G_GINT64_FORMAT " in format %s",
          sectors, dest_val, gst_format_get_name (dest_format));
      break;
    }
    case GST_QUERY_POSITION:{
      GstFormat dest_format;
      gint64 pos_sector;
      gint64 dest_val;

      gst_query_parse_position (query, &dest_format, NULL);

      if (!started)
        return FALSE;

      g_assert (src->priv->tracks != NULL);

      if (dest_format == track_format) {
        GST_LOG_OBJECT (src, "position: track %d", src->priv->cur_track);
        gst_query_set_position (query, track_format, src->priv->cur_track);
        return TRUE;
      }

      if (src->priv->cur_track < 0
          || src->priv->cur_track >= src->priv->num_tracks)
        return FALSE;

      if (src->priv->mode == GST_AUDIO_CD_SRC_MODE_NORMAL) {
        pos_sector =
            src->priv->cur_sector -
            src->priv->tracks[src->priv->cur_track].start;
      } else {
        pos_sector = src->priv->cur_sector - src->priv->tracks[0].start;
      }

      if (!gst_audio_cd_src_convert (src, sector_format, pos_sector,
              dest_format, &dest_val)) {
        return FALSE;
      }

      gst_query_set_position (query, dest_format, dest_val);

      GST_LOG ("position: sector %u, %" G_GINT64_FORMAT " in format %s",
          (guint) pos_sector, dest_val, gst_format_get_name (dest_format));
      break;
    }
    case GST_QUERY_CONVERT:{
      GstFormat src_format, dest_format;
      gint64 src_val, dest_val;

      gst_query_parse_convert (query, &src_format, &src_val, &dest_format,
          NULL);

      if (!gst_audio_cd_src_convert (src, src_format, src_val, dest_format,
              &dest_val)) {
        return FALSE;
      }

      gst_query_set_convert (query, src_format, src_val, dest_format, dest_val);
      break;
    }
    default:{
      GST_DEBUG_OBJECT (src, "unhandled query, chaining up to parent class");
      return GST_BASE_SRC_CLASS (parent_class)->query (basesrc, query);
    }
  }

  return TRUE;
}

static gboolean
gst_audio_cd_src_is_seekable (GstBaseSrc * basesrc)
{
  return TRUE;
}

static gboolean
gst_audio_cd_src_do_seek (GstBaseSrc * basesrc, GstSegment * segment)
{
  GstAudioCdSrc *src = GST_AUDIO_CD_SRC (basesrc);
  gint64 seek_sector;

  GST_DEBUG_OBJECT (src, "segment %" GST_TIME_FORMAT "-%" GST_TIME_FORMAT,
      GST_TIME_ARGS (segment->start), GST_TIME_ARGS (segment->stop));

  if (!gst_audio_cd_src_convert (src, GST_FORMAT_TIME, segment->start,
          sector_format, &seek_sector)) {
    GST_WARNING_OBJECT (src, "conversion failed");
    return FALSE;
  }

  /* we should only really be called when open */
  g_assert (src->priv->cur_track >= 0
      && src->priv->cur_track < src->priv->num_tracks);

  switch (src->priv->mode) {
    case GST_AUDIO_CD_SRC_MODE_NORMAL:
      seek_sector += src->priv->tracks[src->priv->cur_track].start;
      break;
    case GST_AUDIO_CD_SRC_MODE_CONTINUOUS:
      seek_sector += src->priv->tracks[0].start;
      break;
    default:
      g_return_val_if_reached (FALSE);
  }

  src->priv->cur_sector = (gint) seek_sector;

  GST_DEBUG_OBJECT (src, "seek'd to sector %d", src->priv->cur_sector);

  return TRUE;
}

static gboolean
gst_audio_cd_src_handle_track_seek (GstAudioCdSrc * src, gdouble rate,
    GstSeekFlags flags, GstSeekType start_type, gint64 start,
    GstSeekType stop_type, gint64 stop)
{
  GstBaseSrc *basesrc = GST_BASE_SRC (src);
  GstEvent *event;

  if ((flags & GST_SEEK_FLAG_SEGMENT) == GST_SEEK_FLAG_SEGMENT) {
    gint64 start_time = -1;
    gint64 stop_time = -1;

    if (src->priv->mode != GST_AUDIO_CD_SRC_MODE_CONTINUOUS) {
      GST_DEBUG_OBJECT (src, "segment seek in track format is only "
          "supported in CONTINUOUS mode, not in mode %d", src->priv->mode);
      return FALSE;
    }

    switch (start_type) {
      case GST_SEEK_TYPE_SET:
        if (!gst_audio_cd_src_convert (src, track_format, start,
                GST_FORMAT_TIME, &start_time)) {
          GST_DEBUG_OBJECT (src, "cannot convert track %d to time",
              (gint) start);
          return FALSE;
        }
        break;
      case GST_SEEK_TYPE_END:
        if (!gst_audio_cd_src_convert (src, track_format,
                src->priv->num_tracks - start - 1, GST_FORMAT_TIME,
                &start_time)) {
          GST_DEBUG_OBJECT (src, "cannot convert track %d to time",
              (gint) start);
          return FALSE;
        }
        start_type = GST_SEEK_TYPE_SET;
        break;
      case GST_SEEK_TYPE_NONE:
        start_time = -1;
        break;
      default:
        g_return_val_if_reached (FALSE);
    }

    switch (stop_type) {
      case GST_SEEK_TYPE_SET:
        if (!gst_audio_cd_src_convert (src, track_format, stop,
                GST_FORMAT_TIME, &stop_time)) {
          GST_DEBUG_OBJECT (src, "cannot convert track %d to time",
              (gint) stop);
          return FALSE;
        }
        break;
      case GST_SEEK_TYPE_END:
        if (!gst_audio_cd_src_convert (src, track_format,
                src->priv->num_tracks - stop - 1, GST_FORMAT_TIME,
                &stop_time)) {
          GST_DEBUG_OBJECT (src, "cannot convert track %d to time",
              (gint) stop);
          return FALSE;
        }
        stop_type = GST_SEEK_TYPE_SET;
        break;
      case GST_SEEK_TYPE_NONE:
        stop_time = -1;
        break;
      default:
        g_return_val_if_reached (FALSE);
    }

    GST_LOG_OBJECT (src, "seek segment %" GST_TIME_FORMAT "-%" GST_TIME_FORMAT,
        GST_TIME_ARGS (start_time), GST_TIME_ARGS (stop_time));

    /* send fake segment seek event in TIME format to
     * base class, which will hopefully handle the rest */

    event = gst_event_new_seek (rate, GST_FORMAT_TIME, flags, start_type,
        start_time, stop_type, stop_time);

    return GST_BASE_SRC_CLASS (parent_class)->event (basesrc, event);
  }

  /* not a segment seek */

  if (start_type == GST_SEEK_TYPE_NONE) {
    GST_LOG_OBJECT (src, "start seek type is NONE, nothing to do");
    return TRUE;
  }

  if (stop_type != GST_SEEK_TYPE_NONE) {
    GST_WARNING_OBJECT (src, "ignoring stop seek type (expected NONE)");
  }

  if (start < 0 || start >= src->priv->num_tracks) {
    GST_DEBUG_OBJECT (src, "invalid track %" G_GINT64_FORMAT, start);
    return FALSE;
  }

  GST_DEBUG_OBJECT (src, "seeking to track %" G_GINT64_FORMAT, start + 1);

  src->priv->cur_sector = src->priv->tracks[start].start;
  GST_DEBUG_OBJECT (src, "starting at sector %d", src->priv->cur_sector);

  if (src->priv->cur_track != start) {
    src->priv->cur_track = (gint) start;
    src->priv->uri_track = -1;
    src->priv->prev_track = -1;

    gst_audio_cd_src_update_duration (src);
  } else {
    GST_DEBUG_OBJECT (src, "is current track, just seeking back to start");
  }

  /* send fake segment seek event in TIME format to
   * base class (so we get a newsegment etc.) */
  event = gst_event_new_seek (rate, GST_FORMAT_TIME, flags,
      GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_NONE, -1);

  return GST_BASE_SRC_CLASS (parent_class)->event (basesrc, event);
}

static gboolean
gst_audio_cd_src_handle_event (GstBaseSrc * basesrc, GstEvent * event)
{
  GstAudioCdSrc *src = GST_AUDIO_CD_SRC (basesrc);
  gboolean ret = FALSE;

  GST_LOG_OBJECT (src, "handling %s event", GST_EVENT_TYPE_NAME (event));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEEK:{
      GstSeekType start_type, stop_type;
      GstSeekFlags flags;
      GstFormat format;
      gdouble rate;
      gint64 start, stop;

      if (!GST_OBJECT_FLAG_IS_SET (basesrc, GST_BASE_SRC_FLAG_STARTED)) {
        GST_DEBUG_OBJECT (src, "seek failed: device not open");
        break;
      }

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

      if (format == sector_format) {
        GST_DEBUG_OBJECT (src, "seek in sector format not supported");
        break;
      }

      if (format == track_format) {
        ret = gst_audio_cd_src_handle_track_seek (src, rate, flags,
            start_type, start, stop_type, stop);
      } else {
        GST_LOG_OBJECT (src, "let base class handle seek in %s format",
            gst_format_get_name (format));
        event = gst_event_ref (event);
        ret = GST_BASE_SRC_CLASS (parent_class)->event (basesrc, event);
      }
      break;
    }
    case GST_EVENT_TOC_SELECT:{
      guint track_num = 0;
      gchar *uid = NULL;

      gst_event_parse_toc_select (event, &uid);
      if (uid != NULL && sscanf (uid, "audiocd-track-%03u", &track_num) == 1) {
        ret = gst_audio_cd_src_handle_track_seek (src, 1.0, GST_SEEK_FLAG_FLUSH,
            GST_SEEK_TYPE_SET, track_num, GST_SEEK_TYPE_NONE, -1);
      }
      g_free (uid);
      break;
    }
    default:{
      GST_LOG_OBJECT (src, "let base class handle event");
      ret = GST_BASE_SRC_CLASS (parent_class)->event (basesrc, event);
      break;
    }
  }

  return ret;
}

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

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

  return protocols;
}

static gchar *
gst_audio_cd_src_uri_get_uri (GstURIHandler * handler)
{
  GstAudioCdSrc *src = GST_AUDIO_CD_SRC (handler);

  GST_OBJECT_LOCK (src);

  /* FIXME: can we get rid of all that here and just return a copy of the
   * existing URI perhaps? */
  g_free (src->priv->uri);

  if (GST_OBJECT_FLAG_IS_SET (GST_BASE_SRC (src), GST_BASE_SRC_FLAG_STARTED)) {
    src->priv->uri =
        g_strdup_printf ("cdda://%s#%d", src->priv->device,
        (src->priv->uri_track > 0) ? src->priv->uri_track : 1);
  } else {
    src->priv->uri = g_strdup ("cdda://1");
  }

  GST_OBJECT_UNLOCK (src);

  return g_strdup (src->priv->uri);
}

/* Note: gst_element_make_from_uri() might call us with just 'cdda://' as
 * URI and expects us to return TRUE then (and this might be in any state) */

/* We accept URIs of the format cdda://(device#track)|(track) */

static gboolean
gst_audio_cd_src_uri_set_uri (GstURIHandler * handler, const gchar * uri,
    GError ** error)
{
  GstAudioCdSrc *src = GST_AUDIO_CD_SRC (handler);
  const gchar *location;
  gchar *track_number;

  GST_OBJECT_LOCK (src);

  location = uri + 7;
  track_number = g_strrstr (location, "#");
  src->priv->uri_track = 0;
  /* FIXME 0.11: ignore URI fragments that look like device paths for
   * the benefit of rhythmbox and possibly other applications.
   */
  if (track_number && track_number[1] != '/') {
    gchar *device, *nuri = g_strdup (uri);

    track_number = nuri + (track_number - uri);
    *track_number = '\0';
    device = gst_uri_get_location (nuri);
    gst_audio_cd_src_set_device (src, device);
    g_free (device);
    src->priv->uri_track = strtol (track_number + 1, NULL, 10);
    g_free (nuri);
  } else {
    if (*location == '\0')
      src->priv->uri_track = 1;
    else
      src->priv->uri_track = strtol (location, NULL, 10);
  }

  if (src->priv->uri_track < 1)
    goto failed;

  if (src->priv->num_tracks > 0
      && src->priv->tracks != NULL
      && src->priv->uri_track > src->priv->num_tracks)
    goto failed;

  if (src->priv->uri_track > 0 && src->priv->tracks != NULL) {
    GST_OBJECT_UNLOCK (src);

    gst_pad_send_event (GST_BASE_SRC_PAD (src),
        gst_event_new_seek (1.0, track_format, GST_SEEK_FLAG_FLUSH,
            GST_SEEK_TYPE_SET, src->priv->uri_track - 1, GST_SEEK_TYPE_NONE,
            -1));
  } else {
    /* seek will be done in start() */
    GST_OBJECT_UNLOCK (src);
  }

  GST_LOG_OBJECT (handler, "successfully handled uri '%s'", uri);

  return TRUE;

failed:
  {
    GST_OBJECT_UNLOCK (src);
    GST_DEBUG_OBJECT (src, "cannot handle URI '%s'", uri);
    g_set_error_literal (error, GST_URI_ERROR, GST_URI_ERROR_BAD_URI,
        "Could not handle CDDA URI");
    return FALSE;
  }
}

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

  iface->get_type = gst_audio_cd_src_uri_get_type;
  iface->get_uri = gst_audio_cd_src_uri_get_uri;
  iface->set_uri = gst_audio_cd_src_uri_set_uri;
  iface->get_protocols = gst_audio_cd_src_uri_get_protocols;
}

/**
 * gst_audio_cd_src_add_track:
 * @src: a #GstAudioCdSrc
 * @track: address of #GstAudioCdSrcTrack to add
 *
 * CDDA sources use this function from their start vfunc to announce the
 * available data and audio tracks to the base source class. The caller
 * should allocate @track on the stack, the base source will do a shallow
 * copy of the structure (and take ownership of the taglist if there is one).
 *
 * Returns: FALSE on error, otherwise TRUE.
 */

gboolean
gst_audio_cd_src_add_track (GstAudioCdSrc * src, GstAudioCdSrcTrack * track)
{
  g_return_val_if_fail (GST_IS_AUDIO_CD_SRC (src), FALSE);
  g_return_val_if_fail (track != NULL, FALSE);
  g_return_val_if_fail (track->num > 0, FALSE);

  GST_DEBUG_OBJECT (src, "adding track %2u (%2u) [%6u-%6u] [%5s], tags: %"
      GST_PTR_FORMAT, src->priv->num_tracks + 1, track->num, track->start,
      track->end, (track->is_audio) ? "AUDIO" : "DATA ", track->tags);

  if (src->priv->num_tracks > 0) {
    guint end_of_previous_track =
        src->priv->tracks[src->priv->num_tracks - 1].end;

    if (track->start <= end_of_previous_track) {
      GST_WARNING ("track %2u overlaps with previous tracks", track->num);
      return FALSE;
    }
  }

  GST_OBJECT_LOCK (src);

  ++src->priv->num_tracks;
  src->priv->tracks =
      g_renew (GstAudioCdSrcTrack, src->priv->tracks, src->priv->num_tracks);
  src->priv->tracks[src->priv->num_tracks - 1] = *track;

  GST_OBJECT_UNLOCK (src);

  return TRUE;
}

static void
gst_audio_cd_src_update_duration (GstAudioCdSrc * src)
{
  GstBaseSrc *basesrc;
  gint64 dur;

  basesrc = GST_BASE_SRC (src);

  if (!gst_pad_query_duration (GST_BASE_SRC_PAD (src), GST_FORMAT_TIME, &dur)) {
    dur = GST_CLOCK_TIME_NONE;
  }
  basesrc->segment.duration = dur;

  gst_element_post_message (GST_ELEMENT (src),
      gst_message_new_duration_changed (GST_OBJECT (src)));

  GST_LOG_OBJECT (src, "duration updated to %" GST_TIME_FORMAT,
      GST_TIME_ARGS (dur));
}

#define CD_MSF_OFFSET 150

/* the cddb hash function */
static guint
cddb_sum (gint n)
{
  guint ret;

  ret = 0;
  while (n > 0) {
    ret += (n % 10);
    n /= 10;
  }
  return ret;
}

static void
gst_audio_cd_src_calculate_musicbrainz_discid (GstAudioCdSrc * src)
{
  GString *s;
  GChecksum *sha;
  guchar digest[20];
  gchar *ptr;
  gchar tmp[9];
  gulong i;
  unsigned int last_audio_track;
  guint leadout_sector;
  gsize digest_len;

  s = g_string_new (NULL);

  /* MusicBrainz doesn't consider trailing data tracks
   * data tracks up front stay, since the disc has to start with 1 */
  last_audio_track = 0;
  for (i = 0; i < src->priv->num_tracks; i++) {
    if (src->priv->tracks[i].is_audio) {
      last_audio_track = src->priv->tracks[i].num;
    }
  }

  leadout_sector =
      src->priv->tracks[last_audio_track - 1].end + 1 + CD_MSF_OFFSET;

  /* generate SHA digest */
  sha = g_checksum_new (G_CHECKSUM_SHA1);
  g_snprintf (tmp, sizeof (tmp), "%02X", src->priv->tracks[0].num);
  g_string_append_printf (s, "%02X", src->priv->tracks[0].num);
  g_checksum_update (sha, (guchar *) tmp, 2);

  g_snprintf (tmp, sizeof (tmp), "%02X", last_audio_track);
  g_string_append_printf (s, " %02X", last_audio_track);
  g_checksum_update (sha, (guchar *) tmp, 2);

  g_snprintf (tmp, sizeof (tmp), "%08X", leadout_sector);
  g_string_append_printf (s, " %08X", leadout_sector);
  g_checksum_update (sha, (guchar *) tmp, 8);

  for (i = 0; i < 99; i++) {
    if (i < last_audio_track) {
      guint frame_offset = src->priv->tracks[i].start + CD_MSF_OFFSET;

      g_snprintf (tmp, sizeof (tmp), "%08X", frame_offset);
      g_string_append_printf (s, " %08X", frame_offset);
      g_checksum_update (sha, (guchar *) tmp, 8);
    } else {
      g_checksum_update (sha, (guchar *) "00000000", 8);
    }
  }
  digest_len = 20;
  g_checksum_get_digest (sha, (guint8 *) & digest, &digest_len);

  /* re-encode to base64 */
  ptr = g_base64_encode (digest, digest_len);
  g_checksum_free (sha);
  i = strlen (ptr);

  g_assert (i < sizeof (src->priv->mb_discid) + 1);
  memcpy (src->priv->mb_discid, ptr, i);
  src->priv->mb_discid[i] = '\0';
  free (ptr);

  /* Replace '/', '+' and '=' by '_', '.' and '-' as specified on
   * http://musicbrainz.org/doc/DiscIDCalculation
   */
  for (ptr = src->priv->mb_discid; *ptr != '\0'; ptr++) {
    if (*ptr == '/')
      *ptr = '_';
    else if (*ptr == '+')
      *ptr = '.';
    else if (*ptr == '=')
      *ptr = '-';
  }

  GST_DEBUG_OBJECT (src, "musicbrainz-discid      = %s", src->priv->mb_discid);
  GST_DEBUG_OBJECT (src, "musicbrainz-discid-full = %s", s->str);

  gst_tag_list_add (src->tags, GST_TAG_MERGE_REPLACE,
      GST_TAG_CDDA_MUSICBRAINZ_DISCID, src->priv->mb_discid,
      GST_TAG_CDDA_MUSICBRAINZ_DISCID_FULL, s->str, NULL);

  g_string_free (s, TRUE);
}

static void
lba_to_msf (guint sector, guint * p_m, guint * p_s, guint * p_f, guint * p_secs)
{
  guint m, s, f;

  m = sector / SECTORS_PER_MINUTE;
  sector = sector % SECTORS_PER_MINUTE;
  s = sector / SECTORS_PER_SECOND;
  f = sector % SECTORS_PER_SECOND;

  if (p_m)
    *p_m = m;
  if (p_s)
    *p_s = s;
  if (p_f)
    *p_f = f;
  if (p_secs)
    *p_secs = s + (m * 60);
}

static void
gst_audio_cd_src_calculate_cddb_id (GstAudioCdSrc * src)
{
  GString *s;
  guint first_sector = 0, last_sector = 0;
  guint start_secs, end_secs, secs, len_secs;
  guint total_secs, num_audio_tracks;
  guint id, t, i;

  id = 0;
  total_secs = 0;
  num_audio_tracks = 0;

  /* FIXME: do we use offsets and duration of ALL tracks (data + audio)
   * for the CDDB ID calculation, or only audio tracks? */
  for (i = 0; i < src->priv->num_tracks; ++i) {
    if (1) {                    /* src->priv->tracks[i].is_audio) { */
      if (num_audio_tracks == 0) {
        first_sector = src->priv->tracks[i].start + CD_MSF_OFFSET;
      }
      last_sector = src->priv->tracks[i].end + CD_MSF_OFFSET + 1;
      ++num_audio_tracks;

      lba_to_msf (src->priv->tracks[i].start + CD_MSF_OFFSET, NULL, NULL, NULL,
          &secs);

      len_secs =
          (src->priv->tracks[i].end - src->priv->tracks[i].start + 1) / 75;

      GST_DEBUG_OBJECT (src, "track %02u: lsn %6u (%02u:%02u), "
          "length: %u seconds (%02u:%02u)",
          num_audio_tracks, src->priv->tracks[i].start + CD_MSF_OFFSET,
          secs / 60, secs % 60, len_secs, len_secs / 60, len_secs % 60);

      id += cddb_sum (secs);
      total_secs += len_secs;
    }
  }

  /* first_sector = src->priv->tracks[0].start + CD_MSF_OFFSET; */
  lba_to_msf (first_sector, NULL, NULL, NULL, &start_secs);

  /* last_sector = src->priv->tracks[src->priv->num_tracks-1].end + CD_MSF_OFFSET; */
  lba_to_msf (last_sector, NULL, NULL, NULL, &end_secs);

  GST_DEBUG_OBJECT (src, "first_sector = %u = %u secs (%02u:%02u)",
      first_sector, start_secs, start_secs / 60, start_secs % 60);
  GST_DEBUG_OBJECT (src, "last_sector  = %u = %u secs (%02u:%02u)",
      last_sector, end_secs, end_secs / 60, end_secs % 60);

  t = end_secs - start_secs;

  GST_DEBUG_OBJECT (src, "total length = %u secs (%02u:%02u), added title "
      "lengths = %u seconds (%02u:%02u)", t, t / 60, t % 60, total_secs,
      total_secs / 60, total_secs % 60);

  src->priv->discid = ((id % 0xff) << 24 | t << 8 | num_audio_tracks);

  s = g_string_new (NULL);
  g_string_append_printf (s, "%08x", src->priv->discid);

  gst_tag_list_add (src->tags, GST_TAG_MERGE_REPLACE,
      GST_TAG_CDDA_CDDB_DISCID, s->str, NULL);

  g_string_append_printf (s, " %u", src->priv->num_tracks);
  for (i = 0; i < src->priv->num_tracks; ++i) {
    g_string_append_printf (s, " %u",
        src->priv->tracks[i].start + CD_MSF_OFFSET);
  }
  g_string_append_printf (s, " %u", t);

  gst_tag_list_add (src->tags, GST_TAG_MERGE_REPLACE,
      GST_TAG_CDDA_CDDB_DISCID_FULL, s->str, NULL);

  GST_DEBUG_OBJECT (src, "cddb discid = %s", s->str);

  g_string_free (s, TRUE);
}

static void
gst_audio_cd_src_add_tags (GstAudioCdSrc * src)
{
  gint i;

  /* fill in details for each track */
  for (i = 0; i < src->priv->num_tracks; ++i) {
    gint64 duration;
    guint num_sectors;

    if (src->priv->tracks[i].tags == NULL)
      src->priv->tracks[i].tags = gst_tag_list_new_empty ();

    num_sectors = src->priv->tracks[i].end - src->priv->tracks[i].start + 1;
    gst_audio_cd_src_convert (src, sector_format, num_sectors,
        GST_FORMAT_TIME, &duration);

    gst_tag_list_add (src->priv->tracks[i].tags,
        GST_TAG_MERGE_REPLACE,
        GST_TAG_TRACK_NUMBER, i + 1,
        GST_TAG_TRACK_COUNT, src->priv->num_tracks, GST_TAG_DURATION, duration,
        NULL);
  }

  /* now fill in per-album tags and include each track's tags
   * in the album tags, so that interested parties can retrieve
   * the relevant details for each track in one go */

  /* /////////////////////////////// FIXME should we rather insert num_tracks
   * tags by the name of 'track-tags' and have the caller use
   * gst_tag_list_get_value_index() rather than use tag names incl.
   * the track number ?? *////////////////////////////////////////

  gst_tag_list_add (src->tags, GST_TAG_MERGE_REPLACE,
      GST_TAG_TRACK_COUNT, src->priv->num_tracks, NULL);
#if 0
  for (i = 0; i < src->priv->num_tracks; ++i) {
    gst_tag_list_add (src->tags, GST_TAG_MERGE_APPEND,
        GST_TAG_CDDA_TRACK_TAGS, src->priv->tracks[i].tags, NULL);
  }
#endif

  GST_DEBUG ("src->tags = %" GST_PTR_FORMAT, src->tags);
}

static GstToc *
gst_audio_cd_src_make_toc (GstAudioCdSrc * src, GstTocScope scope)
{
  GstToc *toc;
  gint i;

  toc = gst_toc_new (scope);

  for (i = 0; i < src->priv->num_tracks; ++i) {
    GstAudioCdSrcTrack *track;
    gint64 start_time, stop_time;
    GstTocEntry *entry;
    gchar *uid;

    track = &src->priv->tracks[i];

    /* keep uid in sync with toc select event handler below */
    uid = g_strdup_printf ("audiocd-track-%03u", track->num);
    entry = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_TRACK, uid);
    gst_toc_entry_set_tags (entry, gst_tag_list_ref (track->tags));

    gst_audio_cd_src_convert (src, sector_format, track->start,
        GST_FORMAT_TIME, &start_time);
    gst_audio_cd_src_convert (src, sector_format, track->end + 1,
        GST_FORMAT_TIME, &stop_time);

    GST_INFO ("Track %03u  %" GST_TIME_FORMAT " - %" GST_TIME_FORMAT,
        track->num, GST_TIME_ARGS (start_time), GST_TIME_ARGS (stop_time));

    gst_toc_entry_set_start_stop_times (entry, start_time, stop_time);
    gst_toc_append_entry (toc, entry);
    g_free (uid);
  }

  return toc;
}

static void
gst_audio_cd_src_add_toc (GstAudioCdSrc * src)
{
  GstToc *toc;

  /* FIXME: send two TOC events if needed, one global, one current */
  toc = gst_audio_cd_src_make_toc (src, GST_TOC_SCOPE_GLOBAL);

  src->priv->toc_event = gst_event_new_toc (toc, FALSE);

  /* If we're in continuous mode (stream = whole disc), send a TOC event
   * downstream, so matroskamux etc. can write a TOC to indicate where the
   * various tracks are */
  if (src->priv->mode == GST_AUDIO_CD_SRC_MODE_CONTINUOUS)
    src->priv->toc_event = gst_event_new_toc (toc, FALSE);

  src->priv->toc = toc;
}

#if 0
static void
gst_audio_cd_src_add_index_associations (GstAudioCdSrc * src)
{
  gint i;

  for (i = 0; i < src->priv->num_tracks; i++) {
    gint64 sector;

    sector = src->priv->tracks[i].start;
    gst_index_add_association (src->priv->index, src->priv->index_id, GST_ASSOCIATION_FLAG_KEY_UNIT, track_format, i,   /* here we count from 0 */
        sector_format, sector,
        GST_FORMAT_TIME,
        (gint64) (((CD_FRAMESIZE_RAW >> 2) * sector * GST_SECOND) / 44100),
        GST_FORMAT_BYTES, (gint64) (sector << 2), GST_FORMAT_DEFAULT,
        (gint64) ((CD_FRAMESIZE_RAW >> 2) * sector), NULL);
  }
}

static void
gst_audio_cd_src_set_index (GstElement * element, GstIndex * index)
{
  GstAudioCdSrc *src = GST_AUDIO_CD_SRC (element);
  GstIndex *old;

  GST_OBJECT_LOCK (element);
  old = src->priv->index;
  if (old == index) {
    GST_OBJECT_UNLOCK (element);
    return;
  }
  if (index)
    gst_object_ref (index);
  src->priv->index = index;
  GST_OBJECT_UNLOCK (element);
  if (old)
    gst_object_unref (old);

  if (index) {
    gst_index_get_writer_id (index, GST_OBJECT (src), &src->priv->index_id);
    gst_index_add_format (index, src->priv->index_id, track_format);
    gst_index_add_format (index, src->priv->index_id, sector_format);
  }
}


static GstIndex *
gst_audio_cd_src_get_index (GstElement * element)
{
  GstAudioCdSrc *src = GST_AUDIO_CD_SRC (element);
  GstIndex *index;

  GST_OBJECT_LOCK (element);
  if ((index = src->priv->index))
    gst_object_ref (index);
  GST_OBJECT_UNLOCK (element);

  return index;
}
#endif

static gint
gst_audio_cd_src_track_sort_func (gconstpointer a, gconstpointer b,
    gpointer foo)
{
  GstAudioCdSrcTrack *track_a = ((GstAudioCdSrcTrack *) a);
  GstAudioCdSrcTrack *track_b = ((GstAudioCdSrcTrack *) b);

  /* sort data tracks to the end, and audio tracks by track number */
  if (track_a->is_audio == track_b->is_audio)
    return (gint) track_a->num - (gint) track_b->num;

  if (track_a->is_audio) {
    return -1;
  } else {
    return 1;
  }
}

static gboolean
gst_audio_cd_src_start (GstBaseSrc * basesrc)
{
  GstAudioCdSrcClass *klass = GST_AUDIO_CD_SRC_GET_CLASS (basesrc);
  GstAudioCdSrc *src = GST_AUDIO_CD_SRC (basesrc);
  gboolean ret;
  gchar *device = NULL;

  src->priv->discid = 0;
  src->priv->mb_discid[0] = '\0';

  g_assert (klass->open != NULL);

  if (src->priv->device != NULL) {
    device = g_strdup (src->priv->device);
  }
#if 0
  else if (klass->get_default_device != NULL) {
    device = klass->get_default_device (src);
  }
#endif

  if (device == NULL)
    device = g_strdup (DEFAULT_DEVICE);

  GST_LOG_OBJECT (basesrc, "opening device %s", device);

  src->tags = gst_tag_list_new_empty ();

  ret = klass->open (src, device);
  g_free (device);
  device = NULL;

  if (!ret)
    goto open_failed;

  if (src->priv->num_tracks == 0 || src->priv->tracks == NULL)
    goto no_tracks;

  /* need to calculate disc IDs before we ditch the data tracks */
  gst_audio_cd_src_calculate_cddb_id (src);
  gst_audio_cd_src_calculate_musicbrainz_discid (src);

#if 0
  /* adjust sector offsets if necessary */
  if (src->priv->toc_bias) {
    src->priv->toc_offset -= src->priv->tracks[0].start;
  }
  for (i = 0; i < src->priv->num_tracks; ++i) {
    src->priv->tracks[i].start += src->priv->toc_offset;
    src->priv->tracks[i].end += src->priv->toc_offset;
  }
#endif

  /* now that we calculated the various disc IDs,
   * sort the data tracks to end and ignore them */
  src->priv->num_all_tracks = src->priv->num_tracks;

  g_qsort_with_data (src->priv->tracks, src->priv->num_tracks,
      sizeof (GstAudioCdSrcTrack), gst_audio_cd_src_track_sort_func, NULL);

  while (src->priv->num_tracks > 0
      && !src->priv->tracks[src->priv->num_tracks - 1].is_audio)
    --src->priv->num_tracks;

  if (src->priv->num_tracks == 0)
    goto no_tracks;

  gst_audio_cd_src_add_tags (src);
  gst_audio_cd_src_add_toc (src);

#if 0
  if (src->priv->index && GST_INDEX_IS_WRITABLE (src->priv->index))
    gst_audio_cd_src_add_index_associations (src);
#endif

  src->priv->cur_track = 0;
  src->priv->prev_track = -1;

  if (src->priv->uri_track > 0 && src->priv->uri_track <= src->priv->num_tracks) {
    GST_LOG_OBJECT (src, "seek to track %d", src->priv->uri_track);
    src->priv->cur_track = src->priv->uri_track - 1;
    src->priv->uri_track = -1;
    src->priv->mode = GST_AUDIO_CD_SRC_MODE_NORMAL;
  }

  src->priv->cur_sector = src->priv->tracks[src->priv->cur_track].start;
  GST_LOG_OBJECT (src, "starting at sector %d", src->priv->cur_sector);

  gst_audio_cd_src_update_duration (src);

  return TRUE;

  /* ERRORS */
open_failed:
  {
    GST_DEBUG_OBJECT (basesrc, "failed to open device");
    /* subclass (should have) posted an error message with the details */
    gst_audio_cd_src_stop (basesrc);
    return FALSE;
  }
no_tracks:
  {
    GST_DEBUG_OBJECT (src, "no audio tracks");
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
        (_("This CD has no audio tracks")), (NULL));
    gst_audio_cd_src_stop (basesrc);
    return FALSE;
  }
}

static void
gst_audio_cd_src_clear_tracks (GstAudioCdSrc * src)
{
  if (src->priv->tracks != NULL) {
    gint i;

    for (i = 0; i < src->priv->num_all_tracks; ++i) {
      if (src->priv->tracks[i].tags)
        gst_tag_list_unref (src->priv->tracks[i].tags);
    }

    g_free (src->priv->tracks);
    src->priv->tracks = NULL;
  }
  src->priv->num_tracks = 0;
  src->priv->num_all_tracks = 0;
}

static gboolean
gst_audio_cd_src_stop (GstBaseSrc * basesrc)
{
  GstAudioCdSrcClass *klass = GST_AUDIO_CD_SRC_GET_CLASS (basesrc);
  GstAudioCdSrc *src = GST_AUDIO_CD_SRC (basesrc);

  g_assert (klass->close != NULL);

  klass->close (src);

  gst_audio_cd_src_clear_tracks (src);

  if (src->tags) {
    gst_tag_list_unref (src->tags);
    src->tags = NULL;
  }

  gst_event_replace (&src->priv->toc_event, NULL);

  if (src->priv->toc) {
    gst_toc_unref (src->priv->toc);
    src->priv->toc = NULL;
  }

  src->priv->prev_track = -1;
  src->priv->cur_track = -1;

  return TRUE;
}


static GstFlowReturn
gst_audio_cd_src_create (GstPushSrc * pushsrc, GstBuffer ** buffer)
{
  GstAudioCdSrcClass *klass = GST_AUDIO_CD_SRC_GET_CLASS (pushsrc);
  GstAudioCdSrc *src = GST_AUDIO_CD_SRC (pushsrc);
  GstBuffer *buf;
  gboolean eos;

  GstClockTime position = GST_CLOCK_TIME_NONE;
  GstClockTime duration = GST_CLOCK_TIME_NONE;
  gint64 qry_position;

  g_assert (klass->read_sector != NULL);

  switch (src->priv->mode) {
    case GST_AUDIO_CD_SRC_MODE_NORMAL:
      eos =
          (src->priv->cur_sector > src->priv->tracks[src->priv->cur_track].end);
      break;
    case GST_AUDIO_CD_SRC_MODE_CONTINUOUS:
      eos =
          (src->priv->cur_sector >
          src->priv->tracks[src->priv->num_tracks - 1].end);
      src->priv->cur_track =
          gst_audio_cd_src_get_track_from_sector (src, src->priv->cur_sector);
      break;
    default:
      g_return_val_if_reached (GST_FLOW_ERROR);
  }

  if (eos) {
    src->priv->prev_track = -1;
    GST_DEBUG_OBJECT (src, "EOS at sector %d, cur_track=%d, mode=%d",
        src->priv->cur_sector, src->priv->cur_track, src->priv->mode);
    /* base class will send EOS for us */
    return GST_FLOW_EOS;
  }

  if (src->priv->toc_event != NULL) {
    gst_pad_push_event (GST_BASE_SRC_PAD (src), src->priv->toc_event);
    src->priv->toc_event = NULL;
  }

  if (src->priv->prev_track != src->priv->cur_track) {
    GstTagList *tags;

    tags =
        gst_tag_list_merge (src->tags,
        src->priv->tracks[src->priv->cur_track].tags, GST_TAG_MERGE_REPLACE);
    GST_LOG_OBJECT (src, "announcing tags: %" GST_PTR_FORMAT, tags);
    gst_pad_push_event (GST_BASE_SRC_PAD (src), gst_event_new_tag (tags));
    src->priv->prev_track = src->priv->cur_track;

    gst_audio_cd_src_update_duration (src);

    g_object_notify (G_OBJECT (src), "track");
  }

  GST_LOG_OBJECT (src, "asking for sector %u", src->priv->cur_sector);

  buf = klass->read_sector (src, src->priv->cur_sector);

  if (buf == NULL) {
    GST_WARNING_OBJECT (src, "failed to read sector %u", src->priv->cur_sector);
    return GST_FLOW_ERROR;
  }

  if (gst_pad_query_position (GST_BASE_SRC_PAD (src), GST_FORMAT_TIME,
          &qry_position)) {
    gint64 next_ts = 0;

    position = (GstClockTime) qry_position;

    ++src->priv->cur_sector;
    if (gst_pad_query_position (GST_BASE_SRC_PAD (src), GST_FORMAT_TIME,
            &next_ts)) {
      duration = (GstClockTime) (next_ts - qry_position);
    }
    --src->priv->cur_sector;
  }

  /* fallback duration: 4 bytes per sample, 44100 samples per second */
  if (duration == GST_CLOCK_TIME_NONE) {
    duration = gst_util_uint64_scale_int (gst_buffer_get_size (buf) >> 2,
        GST_SECOND, 44100);
  }

  GST_BUFFER_TIMESTAMP (buf) = position;
  GST_BUFFER_DURATION (buf) = duration;

  GST_LOG_OBJECT (src, "pushing sector %d with timestamp %" GST_TIME_FORMAT,
      src->priv->cur_sector, GST_TIME_ARGS (position));

  ++src->priv->cur_sector;

  *buffer = buf;

  return GST_FLOW_OK;
}
