/* GStreamer DVD title source
 * Copyright (C) 1999 Erik Walthinsen <omega@cse.ogi.edu>
 * Copyright (C) 2001 Billy Biggs <vektor@dumbterm.net>.
 * Copyright (C) 2006 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.
 */

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

#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#include "dvdreadsrc.h"

#include <gmodule.h>

#include <gst/gst-i18n-plugin.h>

GST_DEBUG_CATEGORY_STATIC (gstgst_dvd_read_src_debug);
#define GST_CAT_DEFAULT (gstgst_dvd_read_src_debug)

enum
{
  ARG_0,
  ARG_DEVICE,
  ARG_TITLE,
  ARG_CHAPTER,
  ARG_ANGLE
};

static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("video/mpeg, mpegversion=2, systemstream=(boolean)true"));

static GstFormat title_format;
static GstFormat angle_format;
static GstFormat sector_format;
static GstFormat chapter_format;

static gboolean gst_dvd_read_src_start (GstBaseSrc * basesrc);
static gboolean gst_dvd_read_src_stop (GstBaseSrc * basesrc);
static GstFlowReturn gst_dvd_read_src_create (GstPushSrc * pushsrc,
    GstBuffer ** buf);
static gboolean gst_dvd_read_src_src_query (GstBaseSrc * basesrc,
    GstQuery * query);
static gboolean gst_dvd_read_src_src_event (GstBaseSrc * basesrc,
    GstEvent * event);
static gboolean gst_dvd_read_src_goto_title (GstDvdReadSrc * src, gint title,
    gint angle);
static gboolean gst_dvd_read_src_goto_chapter (GstDvdReadSrc * src,
    gint chapter);
static gboolean gst_dvd_read_src_goto_sector (GstDvdReadSrc * src, gint angle);
static void gst_dvd_read_src_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_dvd_read_src_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static GstEvent *gst_dvd_read_src_make_clut_change_event (GstDvdReadSrc * src,
    const guint * clut);
static gboolean gst_dvd_read_src_get_size (GstDvdReadSrc * src, gint64 * size);
static gboolean gst_dvd_read_src_do_seek (GstBaseSrc * src, GstSegment * s);
static gint64 gst_dvd_read_src_convert_timecode (dvd_time_t * time);
static gint gst_dvd_read_src_get_next_cell (GstDvdReadSrc * src,
    pgc_t * pgc, gint cell);
static GstClockTime gst_dvd_read_src_get_time_for_sector (GstDvdReadSrc * src,
    guint sector);
static gint gst_dvd_read_src_get_sector_from_time (GstDvdReadSrc * src,
    GstClockTime ts);

static void gst_dvd_read_src_uri_handler_init (gpointer g_iface,
    gpointer iface_data);

#define gst_dvd_read_src_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstDvdReadSrc, gst_dvd_read_src, GST_TYPE_PUSH_SRC,
    G_IMPLEMENT_INTERFACE (GST_TYPE_URI_HANDLER,
        gst_dvd_read_src_uri_handler_init));

static void
gst_dvd_read_src_finalize (GObject * object)
{
  GstDvdReadSrc *src = GST_DVD_READ_SRC (object);

  g_free (src->location);

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

static void
gst_dvd_read_src_init (GstDvdReadSrc * src)
{
  src->dvd = NULL;
  src->vts_file = NULL;
  src->vmg_file = NULL;
  src->dvd_title = NULL;

  src->location = g_strdup ("/dev/dvd");
  src->first_seek = TRUE;
  src->new_seek = TRUE;
  src->new_cell = TRUE;
  src->change_cell = FALSE;
  src->uri_title = 1;
  src->uri_chapter = 1;
  src->uri_angle = 1;

  src->title_lang_event_pending = NULL;
  src->pending_clut_event = NULL;

  gst_pad_use_fixed_caps (GST_BASE_SRC_PAD (src));
  gst_pad_set_caps (GST_BASE_SRC_PAD (src),
      gst_static_pad_template_get_caps (&srctemplate));
}

static gboolean
gst_dvd_read_src_is_seekable (GstBaseSrc * src)
{
  return TRUE;
}

static void
gst_dvd_read_src_class_init (GstDvdReadSrcClass * klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
  GstPushSrcClass *gstpushsrc_class = GST_PUSH_SRC_CLASS (klass);
  GstBaseSrcClass *gstbasesrc_class = GST_BASE_SRC_CLASS (klass);

  gobject_class->finalize = gst_dvd_read_src_finalize;
  gobject_class->set_property = gst_dvd_read_src_set_property;
  gobject_class->get_property = gst_dvd_read_src_get_property;

  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DEVICE,
      g_param_spec_string ("device", "Device",
          "DVD device location", NULL,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_TITLE,
      g_param_spec_int ("title", "title", "title",
          1, 999, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_CHAPTER,
      g_param_spec_int ("chapter", "chapter", "chapter",
          1, 999, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ANGLE,
      g_param_spec_int ("angle", "angle", "angle",
          1, 999, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  gst_element_class_add_static_pad_template (gstelement_class, &srctemplate);

  gst_element_class_set_static_metadata (gstelement_class, "DVD Source",
      "Source/File/DVD",
      "Access a DVD title/chapter/angle using libdvdread",
      "Erik Walthinsen <omega@cse.ogi.edu>");

  gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_dvd_read_src_start);
  gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_dvd_read_src_stop);
  gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_dvd_read_src_src_query);
  gstbasesrc_class->event = GST_DEBUG_FUNCPTR (gst_dvd_read_src_src_event);
  gstbasesrc_class->do_seek = GST_DEBUG_FUNCPTR (gst_dvd_read_src_do_seek);
  gstbasesrc_class->is_seekable =
      GST_DEBUG_FUNCPTR (gst_dvd_read_src_is_seekable);

  gstpushsrc_class->create = GST_DEBUG_FUNCPTR (gst_dvd_read_src_create);

  title_format = gst_format_register ("title", "DVD title");
  angle_format = gst_format_register ("angle", "DVD angle");
  sector_format = gst_format_register ("sector", "DVD sector");
  chapter_format = gst_format_register ("chapter", "DVD chapter");
}

static gboolean
gst_dvd_read_src_start (GstBaseSrc * basesrc)
{
  GstDvdReadSrc *src = GST_DVD_READ_SRC (basesrc);

  g_return_val_if_fail (src->location != NULL, FALSE);

  GST_DEBUG_OBJECT (src, "Opening DVD '%s'", src->location);

  if ((src->dvd = DVDOpen (src->location)) == NULL)
    goto open_failed;

  /* Load the video manager to find out the information about the titles */
  GST_DEBUG_OBJECT (src, "Loading VMG info");

  if (!(src->vmg_file = ifoOpen (src->dvd, 0)))
    goto ifo_open_failed;

  src->tt_srpt = src->vmg_file->tt_srpt;

  src->title = src->uri_title - 1;
  src->chapter = src->uri_chapter - 1;
  src->angle = src->uri_angle - 1;

  if (!gst_dvd_read_src_goto_title (src, src->title, src->angle))
    goto title_open_failed;

  if (!gst_dvd_read_src_goto_chapter (src, src->chapter))
    goto chapter_open_failed;

  src->new_seek = FALSE;
  src->change_cell = TRUE;

  src->first_seek = TRUE;

  return TRUE;

  /* ERRORS */
open_failed:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
        (_("Could not open DVD")),
        ("DVDOpen(%s) failed: %s", src->location, g_strerror (errno)));
    return FALSE;
  }
ifo_open_failed:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
        (_("Could not open DVD")),
        ("ifoOpen() failed: %s", g_strerror (errno)));
    return FALSE;
  }
title_open_failed:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
        (_("Could not open DVD title %d"), src->uri_title), (NULL));
    return FALSE;
  }
chapter_open_failed:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
        (_("Failed to go to chapter %d of DVD title %d"),
            src->uri_chapter, src->uri_title), (NULL));
    return FALSE;
  }
}

static gboolean
gst_dvd_read_src_stop (GstBaseSrc * basesrc)
{
  GstDvdReadSrc *src = GST_DVD_READ_SRC (basesrc);

  if (src->vts_file) {
    ifoClose (src->vts_file);
    src->vts_file = NULL;
  }
  if (src->vmg_file) {
    ifoClose (src->vmg_file);
    src->vmg_file = NULL;
  }
  if (src->dvd_title) {
    DVDCloseFile (src->dvd_title);
    src->dvd_title = NULL;
  }
  if (src->dvd) {
    DVDClose (src->dvd);
    src->dvd = NULL;
  }
  src->new_cell = TRUE;
  src->new_seek = TRUE;
  src->change_cell = FALSE;
  src->chapter = 0;
  src->title = 0;
  src->need_newsegment = TRUE;
  src->vts_tmapt = NULL;
  if (src->title_lang_event_pending) {
    gst_event_unref (src->title_lang_event_pending);
    src->title_lang_event_pending = NULL;
  }
  if (src->pending_clut_event) {
    gst_event_unref (src->pending_clut_event);
    src->pending_clut_event = NULL;
  }
  if (src->chapter_starts) {
    g_free (src->chapter_starts);
    src->chapter_starts = NULL;
  }

  GST_LOG_OBJECT (src, "closed DVD");

  return TRUE;
}

static void
cur_title_get_chapter_pgc (GstDvdReadSrc * src, gint chapter, gint * p_pgn,
    gint * p_pgc_id, pgc_t ** p_pgc)
{
  pgc_t *pgc;
  gint pgn, pgc_id;

  g_assert (chapter >= 0 && chapter < src->num_chapters);

  pgc_id = src->vts_ptt_srpt->title[src->ttn - 1].ptt[chapter].pgcn;
  pgn = src->vts_ptt_srpt->title[src->ttn - 1].ptt[chapter].pgn;
  pgc = src->vts_file->vts_pgcit->pgci_srp[pgc_id - 1].pgc;

  *p_pgn = pgn;
  *p_pgc_id = pgc_id;
  *p_pgc = pgc;
}

static void
cur_title_get_chapter_bounds (GstDvdReadSrc * src, gint chapter,
    gint * p_first_cell, gint * p_last_cell)
{
  pgc_t *pgc;
  gint pgn, pgc_id, pgn_next_ch;

  g_assert (chapter >= 0 && chapter < src->num_chapters);

  cur_title_get_chapter_pgc (src, chapter, &pgn, &pgc_id, &pgc);

  *p_first_cell = pgc->program_map[pgn - 1] - 1;

  /* last cell is used as a 'up to boundary', not 'up to and including',
   * i.e. it is the first cell not included in the chapter range */
  if (chapter == (src->num_chapters - 1)) {
    *p_last_cell = pgc->nr_of_cells;
  } else {
    pgn_next_ch = src->vts_ptt_srpt->title[src->ttn - 1].ptt[chapter + 1].pgn;
    *p_last_cell = pgc->program_map[pgn_next_ch - 1] - 1;
  }

  GST_DEBUG_OBJECT (src, "Chapter %d bounds: %d %d (within %d cells)",
      chapter, *p_first_cell, *p_last_cell, pgc->nr_of_cells);
}

static gboolean
gst_dvd_read_src_goto_chapter (GstDvdReadSrc * src, gint chapter)
{
  gint i;

  /* make sure the chapter number is valid for this title */
  if (chapter < 0 || chapter >= src->num_chapters) {
    GST_WARNING_OBJECT (src, "invalid chapter %d (only %d available)",
        chapter, src->num_chapters);
    chapter = CLAMP (chapter, 0, src->num_chapters - 1);
  }

  /* determine which program chain we want to watch. This is
   * based on the chapter number */
  cur_title_get_chapter_pgc (src, chapter, &src->pgn, &src->pgc_id,
      &src->cur_pgc);
  cur_title_get_chapter_bounds (src, chapter, &src->start_cell,
      &src->last_cell);

  GST_LOG_OBJECT (src, "Opened chapter %d - cell %d-%d", chapter + 1,
      src->start_cell, src->last_cell);

  /* retrieve position */
  src->cur_pack = 0;
  for (i = 0; i < chapter; i++) {
    gint c1, c2;

    cur_title_get_chapter_bounds (src, i, &c1, &c2);

    while (c1 < c2) {
      src->cur_pack +=
          src->cur_pgc->cell_playback[c1].last_sector -
          src->cur_pgc->cell_playback[c1].first_sector;
      ++c1;
    }
  }

  /* prepare reading for new cell */
  src->new_cell = TRUE;
  src->next_cell = src->start_cell;

  src->chapter = chapter;

  if (src->pending_clut_event)
    gst_event_unref (src->pending_clut_event);

  src->pending_clut_event =
      gst_dvd_read_src_make_clut_change_event (src, src->cur_pgc->palette);

  return TRUE;
}

static void
gst_dvd_read_src_get_chapter_starts (GstDvdReadSrc * src)
{
  GstClockTime uptohere;
  guint c;

  g_free (src->chapter_starts);
  src->chapter_starts = g_new (GstClockTime, src->num_chapters);

  uptohere = (GstClockTime) 0;
  for (c = 0; c < src->num_chapters; ++c) {
    GstClockTime chapter_duration = 0;
    gint cell_start, cell_end, cell;
    gint pgn, pgc_id;
    pgc_t *pgc;

    cur_title_get_chapter_pgc (src, c, &pgn, &pgc_id, &pgc);
    cur_title_get_chapter_bounds (src, c, &cell_start, &cell_end);

    cell = cell_start;
    while (cell < cell_end) {
      dvd_time_t *cell_duration;

      cell_duration = &pgc->cell_playback[cell].playback_time;
      chapter_duration += gst_dvd_read_src_convert_timecode (cell_duration);
      cell = gst_dvd_read_src_get_next_cell (src, pgc, cell);
    }

    src->chapter_starts[c] = uptohere;

    GST_INFO_OBJECT (src, "[%02u] Chapter %02u starts at %" GST_TIME_FORMAT
        ", dur = %" GST_TIME_FORMAT ", cells %d-%d", src->title + 1, c + 1,
        GST_TIME_ARGS (uptohere), GST_TIME_ARGS (chapter_duration),
        cell_start, cell_end);

    uptohere += chapter_duration;
  }
}

static gboolean
gst_dvd_read_src_goto_title (GstDvdReadSrc * src, gint title, gint angle)
{
  GstStructure *s;
  gchar lang_code[3] = { '\0', '\0', '\0' }, *t;
  pgc_t *pgc0;
  gint title_set_nr;
  gint num_titles;
  gint pgn0, pgc0_id;
  gint i;

  /* make sure our title number is valid */
  num_titles = src->tt_srpt->nr_of_srpts;
  GST_INFO_OBJECT (src, "There are %d titles on this DVD", num_titles);
  if (title < 0 || title >= num_titles)
    goto invalid_title;

  src->num_chapters = src->tt_srpt->title[title].nr_of_ptts;
  GST_INFO_OBJECT (src, "Title %d has %d chapters", title + 1,
      src->num_chapters);

  /* make sure the angle number is valid for this title */
  src->num_angles = src->tt_srpt->title[title].nr_of_angles;
  GST_LOG_OBJECT (src, "Title %d has %d angles", title + 1, src->num_angles);
  if (angle < 0 || angle >= src->num_angles) {
    GST_WARNING_OBJECT (src, "Invalid angle %d (only %d available)",
        angle, src->num_angles);
    angle = CLAMP (angle, 0, src->num_angles - 1);
  }

  /* load the VTS information for the title set our title is in */
  title_set_nr = src->tt_srpt->title[title].title_set_nr;
  src->vts_file = ifoOpen (src->dvd, title_set_nr);
  if (src->vts_file == NULL)
    goto ifo_open_failed;

  src->ttn = src->tt_srpt->title[title].vts_ttn;
  src->vts_ptt_srpt = src->vts_file->vts_ptt_srpt;

  /* interactive title? */
  if (src->num_chapters > 0 &&
      src->vts_ptt_srpt->title[src->ttn - 1].ptt[0].pgn == 0) {
    goto commands_only_pgc;
  }

  /* we've got enough info, time to open the title set data */
  src->dvd_title = DVDOpenFile (src->dvd, title_set_nr, DVD_READ_TITLE_VOBS);
  if (src->dvd_title == NULL)
    goto title_open_failed;

  GST_INFO_OBJECT (src, "Opened title %d, angle %d", title + 1, angle);
  src->title = title;
  src->angle = angle;

  /* build event */

  if (src->title_lang_event_pending) {
    gst_event_unref (src->title_lang_event_pending);
    src->title_lang_event_pending = NULL;
  }

  s = gst_structure_new ("application/x-gst-dvd",
      "event", G_TYPE_STRING, "dvd-lang-codes", NULL);

  /* so we can filter out invalid/unused streams (same for all chapters) */
  cur_title_get_chapter_pgc (src, 0, &pgn0, &pgc0_id, &pgc0);

  /* audio */
  for (i = 0; i < src->vts_file->vtsi_mat->nr_of_vts_audio_streams; i++) {
    const audio_attr_t *a;

    /* audio stream present? */
    if (pgc0 != NULL && (pgc0->audio_control[i] & 0x8000) == 0)
      continue;

    a = &src->vts_file->vtsi_mat->vts_audio_attr[i];

    t = g_strdup_printf ("audio-%d-format", i);
    gst_structure_set (s, t, G_TYPE_INT, (int) a->audio_format, NULL);
    g_free (t);
    t = g_strdup_printf ("audio-%d-stream", i);
    gst_structure_set (s, t, G_TYPE_INT, (int) i, NULL);
    g_free (t);

    if (a->lang_type) {
      t = g_strdup_printf ("audio-%d-language", i);
      lang_code[0] = (a->lang_code >> 8) & 0xff;
      lang_code[1] = a->lang_code & 0xff;
      gst_structure_set (s, t, G_TYPE_STRING, lang_code, NULL);
      g_free (t);
    } else {
      lang_code[0] = '\0';
    }

    GST_INFO_OBJECT (src, "[%02d] Audio    %02d: lang='%s', format=%d",
        src->title + 1, i, lang_code, (gint) a->audio_format);
  }

  /* subtitle */
  for (i = 0; i < src->vts_file->vtsi_mat->nr_of_vts_subp_streams; i++) {
    const subp_attr_t *u;
    const video_attr_t *v;
    gint sid;

    /* subpicture stream present? */
    if (pgc0 != NULL && (pgc0->subp_control[i] & 0x80000000) == 0)
      continue;

    u = &src->vts_file->vtsi_mat->vts_subp_attr[i];
    v = &src->vts_file->vtsi_mat->vts_video_attr;

    sid = i;
    if (pgc0 != NULL) {
      if (v->display_aspect_ratio == 0) /* 4:3 */
        sid = (pgc0->subp_control[i] >> 24) & 0x1f;
      else if (v->display_aspect_ratio == 3)    /* 16:9 */
        sid = (pgc0->subp_control[i] >> 8) & 0x1f;
    }

    if (u->type) {
      t = g_strdup_printf ("subpicture-%d-language", i);
      lang_code[0] = (u->lang_code >> 8) & 0xff;
      lang_code[1] = u->lang_code & 0xff;
      gst_structure_set (s, t, G_TYPE_STRING, lang_code, NULL);
      t = g_strdup_printf ("subpicture-%d-stream", i);
      gst_structure_set (s, t, G_TYPE_INT, (int) sid, NULL);
      g_free (t);
      t = g_strdup_printf ("subpicture-%d-format", i);
      gst_structure_set (s, t, G_TYPE_INT, (int) 0, NULL);
      g_free (t);
    } else {
      lang_code[0] = '\0';
    }

    GST_INFO_OBJECT (src, "[%02d] Subtitle %02d: lang='%s', type=%d",
        src->title + 1, sid, lang_code, u->type);
  }

  src->title_lang_event_pending =
      gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s);

  /* dump seek tables */
  src->vts_tmapt = src->vts_file->vts_tmapt;
  if (src->vts_tmapt) {
    gint i, j;

    GST_LOG_OBJECT (src, "nr_of_tmaps = %d", src->vts_tmapt->nr_of_tmaps);
    for (i = 0; i < src->vts_tmapt->nr_of_tmaps; ++i) {
      GST_LOG_OBJECT (src, "======= Table %d ===================", i);
      GST_LOG_OBJECT (src, "Offset relative to VTS_TMAPTI: %d",
          src->vts_tmapt->tmap_offset[i]);
      GST_LOG_OBJECT (src, "Time unit (seconds)          : %d",
          src->vts_tmapt->tmap[i].tmu);
      GST_LOG_OBJECT (src, "Number of entries            : %d",
          src->vts_tmapt->tmap[i].nr_of_entries);
      for (j = 0; j < src->vts_tmapt->tmap[i].nr_of_entries; j++) {
        guint64 time;

        time = (guint64) src->vts_tmapt->tmap[i].tmu * (j + 1) * GST_SECOND;
        GST_LOG_OBJECT (src, "Time: %" GST_TIME_FORMAT " VOBU "
            "Sector: 0x%08x %s", GST_TIME_ARGS (time),
            src->vts_tmapt->tmap[i].map_ent[j] & 0x7fffffff,
            (src->vts_tmapt->tmap[i].map_ent[j] >> 31) ? "discontinuity" : "");
      }
    }
  } else {
    GST_WARNING_OBJECT (src, "no vts_tmapt - seeking will suck");
  }

  gst_dvd_read_src_get_chapter_starts (src);

  return TRUE;

  /* ERRORS */
invalid_title:
  {
    GST_WARNING_OBJECT (src, "Invalid title %d (only %d available)",
        title, num_titles);
    return FALSE;
  }
ifo_open_failed:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
        (_("Could not open DVD title %d"), title_set_nr),
        ("ifoOpen(%d) failed: %s", title_set_nr, g_strerror (errno)));
    return FALSE;
  }
title_open_failed:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
        (_("Could not open DVD title %d"), title_set_nr),
        ("Can't open title VOBS (VTS_%02d_1.VOB)", title_set_nr));
    return FALSE;
  }
commands_only_pgc:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
        (_("Could not open DVD title %d. Interactive titles are not supported "
                "by this element"), title_set_nr),
        ("Commands-only PGC, not supported, use rsndvdbin"));
    return FALSE;
  }
}

/* FIXME: double-check this function, compare against original */
static gint
gst_dvd_read_src_get_next_cell (GstDvdReadSrc * src, pgc_t * pgc, gint cell)
{
  /* Check if we're entering an angle block. */
  if (pgc->cell_playback[cell].block_type != BLOCK_TYPE_ANGLE_BLOCK)
    return (cell + 1);

  while (pgc->cell_playback[cell].block_mode != BLOCK_MODE_LAST_CELL)
    ++cell;

  return cell + 1;
}

/* Returns true if the pack is a NAV pack */
static gboolean
gst_dvd_read_src_is_nav_pack (const guint8 * data, gint lbn, dsi_t * dsi_pack)
{
  if (GST_READ_UINT32_BE (data + 0x26) != 0x000001BF)
    return FALSE;

  /* Check that this is substream 0 (PCI) */
  if (data[0x2c] != 0)
    return FALSE;

  if (GST_READ_UINT32_BE (data + 0x400) != 0x000001BF)
    return FALSE;

  /* Check that this is substream 1 (DSI) */
  if (data[0x406] != 1)
    return FALSE;

  /* Check sizes of PCI and DSI packets */
  if (GST_READ_UINT16_BE (data + 0x2a) != 0x03d4)
    return FALSE;

  if (GST_READ_UINT16_BE (data + 0x404) != 0x03fa)
    return FALSE;

  /* Read the DSI packet into the provided struct and check it */
  navRead_DSI (dsi_pack, (unsigned char *) data + DSI_START_BYTE);
  if (lbn != dsi_pack->dsi_gi.nv_pck_lbn)
    return FALSE;

  return TRUE;
}

/* find time for sector from index, returns NONE if there is no exact match */
static GstClockTime
gst_dvd_read_src_get_time_for_sector (GstDvdReadSrc * src, guint sector)
{
  gint i, j;

  if (src->vts_tmapt == NULL || src->vts_tmapt->nr_of_tmaps == 0)
    return GST_CLOCK_TIME_NONE;

  for (i = 0; i < src->vts_tmapt->nr_of_tmaps; ++i) {
    for (j = 0; j < src->vts_tmapt->tmap[i].nr_of_entries; ++j) {
      if ((src->vts_tmapt->tmap[i].map_ent[j] & 0x7fffffff) == sector)
        return (guint64) src->vts_tmapt->tmap[i].tmu * (j + 1) * GST_SECOND;
    }
  }

  if (sector == 0)
    return (GstClockTime) 0;

  return GST_CLOCK_TIME_NONE;
}

/* returns the sector in the index at (or before) the given time, or -1 */
static gint
gst_dvd_read_src_get_sector_from_time (GstDvdReadSrc * src, GstClockTime ts)
{
  gint sector, j;

  if (src->vts_tmapt == NULL || src->vts_tmapt->nr_of_tmaps < src->ttn)
    return -1;

  sector = src->vts_tmapt->tmap[src->ttn - 1].map_ent[0] & 0x7fffffff;

  for (j = 0; j < src->vts_tmapt->tmap[src->ttn - 1].nr_of_entries; ++j) {
    GstClockTime entry_time;

    entry_time =
        (guint64) src->vts_tmapt->tmap[src->ttn - 1].tmu * (j + 1) * GST_SECOND;
    if (entry_time <= ts) {
      sector = src->vts_tmapt->tmap[src->ttn - 1].map_ent[j] & 0x7fffffff;
    }
    if (entry_time >= ts) {
      return sector;
    }
  }

  if (ts == 0)
    return 0;

  return -1;
}

typedef enum
{
  GST_DVD_READ_OK = 0,
  GST_DVD_READ_ERROR = -1,
  GST_DVD_READ_EOS = -2,
  GST_DVD_READ_AGAIN = -3
} GstDvdReadReturn;

static GstDvdReadReturn
gst_dvd_read_src_read (GstDvdReadSrc * src, gint angle, gint new_seek,
    GstBuffer ** p_buf)
{
  GstBuffer *buf;
  GstSegment *seg;
  guint8 oneblock[DVD_VIDEO_LB_LEN];
  dsi_t dsi_pack;
  guint next_vobu, cur_output_size;
  gint len;
  gint retries;
  gint64 next_time;
  GstMapInfo map;

  seg = &(GST_BASE_SRC (src)->segment);

  /* playback by cell in this pgc, starting at the cell for our chapter */
  if (new_seek)
    src->cur_cell = src->start_cell;

again:

  if (src->cur_cell >= src->last_cell) {
    /* advance to next chapter */
    if (src->chapter == (src->num_chapters - 1) ||
        (seg->format == chapter_format && seg->stop != -1 &&
            src->chapter == (seg->stop - 1))) {
      GST_DEBUG_OBJECT (src, "end of chapter segment");
      goto eos;
    }

    GST_INFO_OBJECT (src, "end of chapter %d, switch to next",
        src->chapter + 1);

    ++src->chapter;
    gst_dvd_read_src_goto_chapter (src, src->chapter);

    return GST_DVD_READ_AGAIN;
  }

  if (src->new_cell || new_seek) {
    if (!new_seek) {
      src->cur_cell = src->next_cell;
      if (src->cur_cell >= src->last_cell) {
        GST_LOG_OBJECT (src, "last cell in chapter");
        goto again;
      }
    }

    /* take angle into account */
    if (src->cur_pgc->cell_playback[src->cur_cell].block_type
        == BLOCK_TYPE_ANGLE_BLOCK)
      src->cur_cell += angle;

    /* calculate next cell */
    src->next_cell =
        gst_dvd_read_src_get_next_cell (src, src->cur_pgc, src->cur_cell);

    /* we loop until we're out of this cell */
    src->cur_pack = src->cur_pgc->cell_playback[src->cur_cell].first_sector;
    src->new_cell = FALSE;
    GST_DEBUG_OBJECT (src, "Starting new cell %d @ pack %d", src->cur_cell,
        src->cur_pack);
  }

  if (src->cur_pack >= src->cur_pgc->cell_playback[src->cur_cell].last_sector) {
    src->new_cell = TRUE;
    GST_LOG_OBJECT (src, "Beyond last sector for cell %d, going to next cell",
        src->cur_cell);
    return GST_DVD_READ_AGAIN;
  }

  /* read NAV packet */
  retries = 0;
nav_retry:
  retries++;

  len = DVDReadBlocks (src->dvd_title, src->cur_pack, 1, oneblock);
  if (len != 1)
    goto read_error;

  if (!gst_dvd_read_src_is_nav_pack (oneblock, src->cur_pack, &dsi_pack)) {
    GST_LOG_OBJECT (src, "Skipping nav packet @ pack %d", src->cur_pack);
    src->cur_pack++;

    if (retries < 2000) {
      goto nav_retry;
    } else {
      GST_LOG_OBJECT (src, "No nav packet @ pack %d after 2000 blocks",
          src->cur_pack);
      goto read_error;
    }
  }

  /* determine where we go next. These values are the ones we
   * mostly care about */
  cur_output_size = dsi_pack.dsi_gi.vobu_ea + 1;

  /* If we're not at the end of this cell, we can determine the next
   * VOBU to display using the VOBU_SRI information section of the
   * DSI.  Using this value correctly follows the current angle,
   * avoiding the doubled scenes in The Matrix, and makes our life
   * really happy.
   *
   * Otherwise, we set our next address past the end of this cell to
   * force the code above to go to the next cell in the program. */
  if (dsi_pack.vobu_sri.next_vobu != SRI_END_OF_CELL) {
    next_vobu = src->cur_pack + (dsi_pack.vobu_sri.next_vobu & 0x7fffffff);
  } else {
    next_vobu = src->cur_pgc->cell_playback[src->cur_cell].last_sector + 1;
  }

  g_assert (cur_output_size < 1024);

  /* create the buffer (TODO: use buffer pool?) */
  buf =
      gst_buffer_new_allocate (NULL, cur_output_size * DVD_VIDEO_LB_LEN, NULL);

  GST_LOG_OBJECT (src, "Going to read %u sectors @ pack %d", cur_output_size,
      src->cur_pack);

  gst_buffer_map (buf, &map, GST_MAP_WRITE);
  /* read in and output cursize packs */
  len =
      DVDReadBlocks (src->dvd_title, src->cur_pack, cur_output_size, map.data);

  if (len != cur_output_size)
    goto block_read_error;

  gst_buffer_unmap (buf, &map);
  gst_buffer_resize (buf, 0, cur_output_size * DVD_VIDEO_LB_LEN);
  /* GST_BUFFER_OFFSET (buf) = priv->cur_pack * DVD_VIDEO_LB_LEN; */
  GST_BUFFER_TIMESTAMP (buf) =
      gst_dvd_read_src_get_time_for_sector (src, src->cur_pack);

  *p_buf = buf;

  GST_LOG_OBJECT (src, "Read %u sectors", cur_output_size);

  src->cur_pack = next_vobu;

  next_time = GST_BUFFER_TIMESTAMP (buf);
  if (GST_CLOCK_TIME_IS_VALID (next_time) && seg->format == GST_FORMAT_TIME &&
      GST_CLOCK_TIME_IS_VALID (seg->stop) &&
      next_time > seg->stop + 5 * GST_SECOND) {
    GST_DEBUG_OBJECT (src, "end of TIME segment");
    goto eos;
  }

  return GST_DVD_READ_OK;

  /* ERRORS */
eos:
  {
    GST_INFO_OBJECT (src, "Reached end-of-segment/stream - EOS");
    return GST_DVD_READ_EOS;
  }
read_error:
  {
    GST_ERROR_OBJECT (src, "Read failed for block %d", src->cur_pack);
    return GST_DVD_READ_ERROR;
  }
block_read_error:
  {
    GST_ERROR_OBJECT (src, "Read failed for %d blocks at %d",
        cur_output_size, src->cur_pack);
    gst_buffer_unmap (buf, &map);
    gst_buffer_unref (buf);
    return GST_DVD_READ_ERROR;
  }
}

/* we don't cache the result on purpose */
static gboolean
gst_dvd_read_descrambler_available (void)
{
  GModule *module;
  gpointer sym;
  gsize res;

  module = g_module_open ("libdvdcss", 0);
  if (module != NULL) {
    res = g_module_symbol (module, "dvdcss_open", &sym);
    g_module_close (module);
  } else {
    res = FALSE;
  }

  return res;
}

static GstFlowReturn
gst_dvd_read_src_create (GstPushSrc * pushsrc, GstBuffer ** p_buf)
{
  GstDvdReadSrc *src = GST_DVD_READ_SRC (pushsrc);
  GstPad *srcpad;
  gint res;

  g_return_val_if_fail (src->dvd != NULL, GST_FLOW_ERROR);

  srcpad = GST_BASE_SRC (src)->srcpad;

  if (src->need_newsegment) {
    GstSegment seg;

    gst_segment_init (&seg, GST_FORMAT_BYTES);
    seg.start = src->cur_pack * DVD_VIDEO_LB_LEN;
    seg.stop = -1;
    seg.time = 0;
    gst_pad_push_event (srcpad, gst_event_new_segment (&seg));
    src->need_newsegment = FALSE;
  }

  if (src->new_seek) {
    gst_dvd_read_src_goto_title (src, src->title, src->angle);
    gst_dvd_read_src_goto_chapter (src, src->chapter);

    src->new_seek = FALSE;
    src->change_cell = TRUE;
  }

  if (src->title_lang_event_pending) {
    gst_pad_push_event (srcpad, src->title_lang_event_pending);
    src->title_lang_event_pending = NULL;
  }

  if (src->pending_clut_event) {
    gst_pad_push_event (srcpad, src->pending_clut_event);
    src->pending_clut_event = NULL;
  }

  /* read it in */
  do {
    res = gst_dvd_read_src_read (src, src->angle, src->change_cell, p_buf);
  } while (res == GST_DVD_READ_AGAIN);

  switch (res) {
    case GST_DVD_READ_ERROR:{
      /* FIXME: figure out a way to detect if scrambling is the problem */
      if (!gst_dvd_read_descrambler_available ()) {
        GST_ELEMENT_ERROR (src, RESOURCE, READ,
            (_("Could not read DVD. This may be because the DVD is encrypted "
                    "and a DVD decryption library is not installed.")), (NULL));
      } else {
        GST_ELEMENT_ERROR (src, RESOURCE, READ, (_("Could not read DVD.")),
            (NULL));
      }
      return GST_FLOW_ERROR;
    }
    case GST_DVD_READ_EOS:{
      return GST_FLOW_EOS;
    }
    case GST_DVD_READ_OK:{
      src->change_cell = FALSE;
      return GST_FLOW_OK;
    }
    default:
      break;
  }

  g_return_val_if_reached (GST_FLOW_EOS);
}

static void
gst_dvd_read_src_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstDvdReadSrc *src = GST_DVD_READ_SRC (object);
  gboolean started;

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

  switch (prop_id) {
    case ARG_DEVICE:{
      if (started) {
        g_warning ("%s: property '%s' needs to be set before the device is "
            "opened", GST_ELEMENT_NAME (src), pspec->name);
        break;
      }

      g_free (src->location);
      /* clear the filename if we get a NULL (is that possible?) */
      if (g_value_get_string (value) == NULL) {
        src->location = g_strdup ("/dev/dvd");
      } else {
        src->location = g_strdup (g_value_get_string (value));
      }
      break;
    }
    case ARG_TITLE:
      src->uri_title = g_value_get_int (value);
      if (started) {
        src->title = src->uri_title - 1;
        src->new_seek = TRUE;
      }
      break;
    case ARG_CHAPTER:
      src->uri_chapter = g_value_get_int (value);
      if (started) {
        src->chapter = src->uri_chapter - 1;
        src->new_seek = TRUE;
      }
      break;
    case ARG_ANGLE:
      src->uri_angle = g_value_get_int (value);
      if (started) {
        src->angle = src->uri_angle - 1;
      }
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }

  GST_OBJECT_UNLOCK (src);
}

static void
gst_dvd_read_src_get_property (GObject * object, guint prop_id, GValue * value,
    GParamSpec * pspec)
{
  GstDvdReadSrc *src = GST_DVD_READ_SRC (object);

  GST_OBJECT_LOCK (src);

  switch (prop_id) {
    case ARG_DEVICE:
      g_value_set_string (value, src->location);
      break;
    case ARG_TITLE:
      g_value_set_int (value, src->uri_title);
      break;
    case ARG_CHAPTER:
      g_value_set_int (value, src->uri_chapter);
      break;
    case ARG_ANGLE:
      g_value_set_int (value, src->uri_angle);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }

  GST_OBJECT_UNLOCK (src);
}

static gboolean
gst_dvd_read_src_get_size (GstDvdReadSrc * src, gint64 * size)
{
  gboolean ret = FALSE;

  if (src->dvd_title) {
    gssize blocks;

    blocks = DVDFileSize (src->dvd_title);
    if (blocks >= 0) {
      *size = (gint64) blocks *DVD_VIDEO_LB_LEN;

      ret = TRUE;
    } else {
      GST_WARNING_OBJECT (src, "DVDFileSize(%p) failed!", src->dvd_title);
    }
  }

  return ret;
}

/*** Querying and seeking ***/

static gboolean
gst_dvd_read_src_handle_seek_event (GstDvdReadSrc * src, GstEvent * event)
{
  GstSeekFlags flags;
  GstSeekType cur_type, end_type;
  gint64 new_off, total;
  GstFormat format;
  GstPad *srcpad;
  gboolean query_ok;
  gdouble rate;

  gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &new_off,
      &end_type, NULL);

  if (rate <= 0.0) {
    GST_DEBUG_OBJECT (src, "cannot do backwards playback yet");
    return FALSE;
  }

  if (end_type != GST_SEEK_TYPE_NONE) {
    if ((format != chapter_format && format != GST_FORMAT_TIME) ||
        end_type != GST_SEEK_TYPE_SET) {
      GST_DEBUG_OBJECT (src, "end seek type not supported");
      return FALSE;
    }
  }

  if (cur_type != GST_SEEK_TYPE_SET) {
    GST_DEBUG_OBJECT (src, "only SEEK_TYPE_SET is supported");
    return FALSE;
  }

  if (format == angle_format) {
    GST_OBJECT_LOCK (src);
    if (new_off < 0 || new_off >= src->num_angles) {
      GST_OBJECT_UNLOCK (src);
      GST_DEBUG_OBJECT (src, "invalid angle %d, only %d available",
          src->num_angles, src->num_angles);
      return FALSE;
    }
    src->angle = (gint) new_off;
    GST_OBJECT_UNLOCK (src);
    GST_DEBUG_OBJECT (src, "switched to angle %d", (gint) new_off + 1);
    return TRUE;
  }

  if (format != chapter_format && format != title_format &&
      format != GST_FORMAT_BYTES && format != GST_FORMAT_TIME) {
    GST_DEBUG_OBJECT (src, "unsupported seek format %d (%s)", format,
        gst_format_get_name (format));
    return FALSE;
  }

  if (format == GST_FORMAT_BYTES) {
    GST_DEBUG_OBJECT (src, "Requested seek to byte %" G_GUINT64_FORMAT,
        new_off);
  } else if (format == GST_FORMAT_TIME) {
    GST_DEBUG_OBJECT (src, "Requested seek to time %" GST_TIME_FORMAT,
        GST_TIME_ARGS (new_off));
    if (gst_dvd_read_src_get_sector_from_time (src, new_off) < 0) {
      GST_DEBUG_OBJECT (src, "Can't find sector for requested time");
      return FALSE;
    }
  }

  srcpad = GST_BASE_SRC_PAD (src);

  /* check whether the seek looks reasonable (ie within possible range) */
  if (format == GST_FORMAT_BYTES) {
    GST_OBJECT_LOCK (src);
    query_ok = gst_dvd_read_src_get_size (src, &total);
    GST_OBJECT_UNLOCK (src);
  } else {
    query_ok = gst_pad_query_duration (srcpad, format, &total);
  }

  if (!query_ok) {
    GST_DEBUG_OBJECT (src, "Failed to query duration in format %s",
        gst_format_get_name (format));
    return FALSE;
  }

  GST_DEBUG_OBJECT (src, "Total      %s: %12" G_GINT64_FORMAT,
      gst_format_get_name (format), total);
  GST_DEBUG_OBJECT (src, "Seek to    %s: %12" G_GINT64_FORMAT,
      gst_format_get_name (format), new_off);

  if (new_off >= total) {
    GST_DEBUG_OBJECT (src, "Seek position out of range");
    return FALSE;
  }

  /* set segment to seek format; this allows us to use the do_seek
   * virtual function and let the base source handle all the tricky
   * stuff for us. We don't use the segment internally anyway */
  /* FIXME: can't take the stream lock here - what to do? */
  GST_OBJECT_LOCK (src);
  GST_BASE_SRC (src)->segment.format = format;
  GST_BASE_SRC (src)->segment.start = 0;
  GST_BASE_SRC (src)->segment.stop = total;
  GST_BASE_SRC (src)->segment.duration = total;
  GST_OBJECT_UNLOCK (src);

  return GST_BASE_SRC_CLASS (parent_class)->event (GST_BASE_SRC (src), event);
}

static void
gst_dvd_read_src_get_sector_bounds (GstDvdReadSrc * src, gint * first,
    gint * last)
{
  gint c1, c2, tmp;
  cur_title_get_chapter_bounds (src, 0, &c1, &tmp);
  cur_title_get_chapter_bounds (src, src->num_chapters - 1, &tmp, &c2);
  *first = src->cur_pgc->cell_playback[c1].first_sector;
  *last = src->cur_pgc->cell_playback[c2].last_sector;
}

static gboolean
gst_dvd_read_src_do_seek (GstBaseSrc * basesrc, GstSegment * s)
{
  GstDvdReadSrc *src;

  src = GST_DVD_READ_SRC (basesrc);

  GST_DEBUG_OBJECT (src, "Seeking to %s: %12" G_GINT64_FORMAT,
      gst_format_get_name (s->format), s->position);

  /* Ignore the first seek to 0, as it breaks starting playback
   * from another chapter by seeking back to sector 0 */
  if (src->first_seek && s->format == GST_FORMAT_BYTES && s->start == 0) {
    src->first_seek = FALSE;
    return TRUE;
  }

  if (s->format == sector_format || s->format == GST_FORMAT_BYTES
      || s->format == GST_FORMAT_TIME) {
    guint old;

    old = src->cur_pack;

    if (s->format == sector_format) {
      gint first, last;
      gst_dvd_read_src_get_sector_bounds (src, &first, &last);
      GST_DEBUG_OBJECT (src, "Format is sector, seeking to %" G_GINT64_FORMAT,
          s->position);
      src->cur_pack = s->position;
      if (src->cur_pack < first)
        src->cur_pack = first;
      if (src->cur_pack > last)
        src->cur_pack = last;
    } else if (s->format == GST_FORMAT_TIME) {
      gint sector;
      GST_DEBUG_OBJECT (src, "Format is time");

      sector = gst_dvd_read_src_get_sector_from_time (src, s->position);

      GST_DEBUG_OBJECT (src, "Time %" GST_TIME_FORMAT " => sector %d",
          GST_TIME_ARGS (s->position), sector);

      /* really shouldn't happen, we've checked this earlier ... */
      g_return_val_if_fail (sector >= 0, FALSE);

      src->cur_pack = sector;
    } else {
      /* byte format */
      gint first, last;
      gst_dvd_read_src_get_sector_bounds (src, &first, &last);
      GST_DEBUG_OBJECT (src, "Format is byte");
      src->cur_pack = s->position / DVD_VIDEO_LB_LEN;
      if (((gint64) src->cur_pack * DVD_VIDEO_LB_LEN) != s->position) {
        GST_LOG_OBJECT (src, "rounded down offset %" G_GINT64_FORMAT " => %"
            G_GINT64_FORMAT, s->position,
            (gint64) src->cur_pack * DVD_VIDEO_LB_LEN);
      }
      src->cur_pack += first;
    }

    if (!gst_dvd_read_src_goto_sector (src, src->angle)) {
      GST_DEBUG_OBJECT (src, "seek to sector 0x%08x failed", src->cur_pack);
      src->cur_pack = old;
      return FALSE;
    }

    GST_LOG_OBJECT (src, "seek to sector 0x%08x ok", src->cur_pack);
  } else if (s->format == chapter_format) {
    if (!gst_dvd_read_src_goto_chapter (src, (gint) s->position)) {
      GST_DEBUG_OBJECT (src, "seek to chapter %d failed",
          (gint) s->position + 1);
      return FALSE;
    }
    GST_INFO_OBJECT (src, "seek to chapter %d ok", (gint) s->position + 1);
    src->chapter = s->position;
  } else if (s->format == title_format) {
    if (!gst_dvd_read_src_goto_title (src, (gint) s->position, src->angle) ||
        !gst_dvd_read_src_goto_chapter (src, 0)) {
      GST_DEBUG_OBJECT (src, "seek to title %d failed", (gint) s->position);
      return FALSE;
    }
    src->title = (gint) s->position;
    src->chapter = 0;
    GST_INFO_OBJECT (src, "seek to title %d ok", src->title + 1);
  } else {
    g_return_val_if_reached (FALSE);
  }

  src->need_newsegment = TRUE;
  return TRUE;
}

static gboolean
gst_dvd_read_src_src_event (GstBaseSrc * basesrc, GstEvent * event)
{
  GstDvdReadSrc *src = GST_DVD_READ_SRC (basesrc);
  gboolean res;

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

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEEK:
      res = gst_dvd_read_src_handle_seek_event (src, event);
      break;
    default:
      res = GST_BASE_SRC_CLASS (parent_class)->event (basesrc, event);
      break;
  }

  return res;
}

static GstEvent *
gst_dvd_read_src_make_clut_change_event (GstDvdReadSrc * src,
    const guint * clut)
{
  GstStructure *structure;
  gchar name[16];
  gint i;

  structure = gst_structure_new ("application/x-gst-dvd",
      "event", G_TYPE_STRING, "dvd-spu-clut-change", NULL);

  /* Create a separate field for each value in the table. */
  for (i = 0; i < 16; i++) {
    g_snprintf (name, sizeof (name), "clut%02d", i);
    gst_structure_set (structure, name, G_TYPE_INT, (int) clut[i], NULL);
  }

  /* Create the DVD event and put the structure into it. */
  return gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, structure);
}

static gint64
gst_dvd_read_src_convert_timecode (dvd_time_t * time)
{
  gint64 ret_time;
  const gint64 one_hour = 3600 * GST_SECOND;
  const gint64 one_min = 60 * GST_SECOND;

  g_return_val_if_fail ((time->hour >> 4) < 0xa
      && (time->hour & 0xf) < 0xa, -1);
  g_return_val_if_fail ((time->minute >> 4) < 0x7
      && (time->minute & 0xf) < 0xa, -1);
  g_return_val_if_fail ((time->second >> 4) < 0x7
      && (time->second & 0xf) < 0xa, -1);

  ret_time = ((time->hour >> 4) * 10 + (time->hour & 0xf)) * one_hour;
  ret_time += ((time->minute >> 4) * 10 + (time->minute & 0xf)) * one_min;
  ret_time += ((time->second >> 4) * 10 + (time->second & 0xf)) * GST_SECOND;

  return ret_time;
}

static gboolean
gst_dvd_read_src_do_duration_query (GstDvdReadSrc * src, GstQuery * query)
{
  GstFormat format;
  gint64 val;

  gst_query_parse_duration (query, &format, NULL);

  switch (format) {
    case GST_FORMAT_TIME:{
      if (src->cur_pgc == NULL)
        return FALSE;
      val = gst_dvd_read_src_convert_timecode (&src->cur_pgc->playback_time);
      if (val < 0)
        return FALSE;
      break;
    }
    case GST_FORMAT_BYTES:{
      if (!gst_dvd_read_src_get_size (src, &val))
        return FALSE;
      break;
    }
    default:{
      if (format == sector_format) {
        val = DVDFileSize (src->dvd_title);
      } else if (format == title_format) {
        val = src->tt_srpt->nr_of_srpts;
      } else if (format == chapter_format) {
        val = src->num_chapters;
      } else if (format == angle_format) {
        val = src->tt_srpt->title[src->title].nr_of_angles;
      } else {
        GST_DEBUG_OBJECT (src, "Don't know how to handle format %d (%s)",
            format, gst_format_get_name (format));
        return FALSE;
      }
      break;
    }
  }

  GST_LOG_OBJECT (src, "duration = %" G_GINT64_FORMAT " %s", val,
      gst_format_get_name (format));

  gst_query_set_duration (query, format, val);
  return TRUE;
}

static gboolean
gst_dvd_read_src_do_position_query (GstDvdReadSrc * src, GstQuery * query)
{
  GstFormat format;
  gint64 val;

  gst_query_parse_position (query, &format, NULL);

  switch (format) {
    case GST_FORMAT_BYTES:{
      val = (gint64) src->cur_pack * DVD_VIDEO_LB_LEN;
      break;
    }
    default:{
      if (format == sector_format) {
        val = src->cur_pack;
      } else if (format == title_format) {
        val = src->title;
      } else if (format == chapter_format) {
        val = src->chapter;
      } else if (format == angle_format) {
        val = src->angle;
      } else {
        GST_DEBUG_OBJECT (src, "Don't know how to handle format %d (%s)",
            format, gst_format_get_name (format));
        return FALSE;
      }
      break;
    }
  }

  GST_LOG_OBJECT (src, "position = %" G_GINT64_FORMAT " %s", val,
      gst_format_get_name (format));

  gst_query_set_position (query, format, val);
  return TRUE;
}

static gboolean
gst_dvd_read_src_do_convert_query (GstDvdReadSrc * src, GstQuery * query)
{
  GstFormat src_format, dest_format;
  gboolean ret = FALSE;
  gint64 src_val, dest_val = -1;

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

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

  /* Formats to consider: TIME, DEFAULT, BYTES, title, chapter, sector.
   * Note: title and chapter are counted as starting from 0 here, just like
   * in the context of seek events. Another note: DEFAULT format is undefined */

  if (src_format == GST_FORMAT_BYTES) {
    src_format = sector_format;
    src_val /= DVD_VIDEO_LB_LEN;
  }

  if (src_format == sector_format) {
    /* SECTOR => xyz */
    if (dest_format == GST_FORMAT_TIME && src_val < G_MAXUINT) {
      dest_val = gst_dvd_read_src_get_time_for_sector (src, (guint) src_val);
      ret = (dest_val >= 0);
    } else if (dest_format == GST_FORMAT_BYTES) {
      dest_val = src_val * DVD_VIDEO_LB_LEN;
      ret = TRUE;
    } else {
      ret = FALSE;
    }
  } else if (src_format == title_format) {
    /* TITLE => xyz */
    if (dest_format == GST_FORMAT_TIME) {
      /* not really true, but we use this to trick the base source into
       * handling seeks in title-format for us (the source won't know that
       * we changed the title in this case) (changing titles should really
       * be done with an interface rather than a seek, but for now we're
       * stuck with this mechanism. Fix in 0.11) */
      dest_val = (GstClockTime) 0;
      ret = TRUE;
    } else {
      ret = FALSE;
    }
  } else if (src_format == chapter_format) {
    /* CHAPTER => xyz */
    if (dest_format == GST_FORMAT_TIME) {
      if (src->num_chapters >= 0 && src_val < src->num_chapters) {
        dest_val = src->chapter_starts[src_val];
        ret = TRUE;
      }
    } else if (dest_format == sector_format) {
    } else {
      ret = FALSE;
    }
  } else if (src_format == GST_FORMAT_TIME) {
    /* TIME => xyz */
    if (dest_format == sector_format || dest_format == GST_FORMAT_BYTES) {
      dest_val = gst_dvd_read_src_get_sector_from_time (src, src_val);
      ret = (dest_val >= 0);
      if (dest_format == GST_FORMAT_BYTES)
        dest_val *= DVD_VIDEO_LB_LEN;
    } else if (dest_format == chapter_format) {
      if (src->chapter_starts != NULL) {
        gint i;

        for (i = src->num_chapters - 1; i >= 0; --i) {
          if (src->chapter_starts && src->chapter_starts[i] >= src_val) {
            dest_val = i;
            ret = TRUE;
            break;
          }
        }
      } else {
        ret = FALSE;
      }
    } else {
      ret = FALSE;
    }
  } else {
    ret = FALSE;
  }

done:

  if (ret) {
    gst_query_set_convert (query, src_format, src_val, dest_format, dest_val);
  }

  return ret;
}

static gboolean
gst_dvd_read_src_src_query (GstBaseSrc * basesrc, GstQuery * query)
{
  GstDvdReadSrc *src = GST_DVD_READ_SRC (basesrc);
  gboolean res = TRUE;

  GST_LOG_OBJECT (src, "handling %s query", GST_QUERY_TYPE_NAME (query));

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_DURATION:
      GST_OBJECT_LOCK (src);
      if (GST_OBJECT_FLAG_IS_SET (src, GST_BASE_SRC_FLAG_STARTED)) {
        res = gst_dvd_read_src_do_duration_query (src, query);
      } else {
        GST_DEBUG_OBJECT (src, "query failed: not started");
        res = FALSE;
      }
      GST_OBJECT_UNLOCK (src);
      break;
    case GST_QUERY_POSITION:
      GST_OBJECT_LOCK (src);
      if (GST_OBJECT_FLAG_IS_SET (src, GST_BASE_SRC_FLAG_STARTED)) {
        res = gst_dvd_read_src_do_position_query (src, query);
      } else {
        GST_DEBUG_OBJECT (src, "query failed: not started");
        res = FALSE;
      }
      GST_OBJECT_UNLOCK (src);
      break;
    case GST_QUERY_CONVERT:
      GST_OBJECT_LOCK (src);
      if (GST_OBJECT_FLAG_IS_SET (src, GST_BASE_SRC_FLAG_STARTED)) {
        res = gst_dvd_read_src_do_convert_query (src, query);
      } else {
        GST_DEBUG_OBJECT (src, "query failed: not started");
        res = FALSE;
      }
      GST_OBJECT_UNLOCK (src);
      break;
    default:
      res = GST_BASE_SRC_CLASS (parent_class)->query (basesrc, query);
      break;
  }

  return res;
}

static gboolean
gst_dvd_read_src_goto_sector (GstDvdReadSrc * src, int angle)
{
  gint seek_to = src->cur_pack;
  gint chapter, next, cur, i;

  /* retrieve position */
  src->cur_pack = 0;
  GST_DEBUG_OBJECT (src, "Goto sector %d, angle %d, within %d chapters",
      seek_to, angle, src->num_chapters);

  for (i = 0; i < src->num_chapters; i++) {
    gint c1, c2;

    cur_title_get_chapter_bounds (src, i, &c1, &c2);
    GST_DEBUG_OBJECT (src, " Looking in chapter %d, bounds: %d %d", i, c1, c2);

    for (next = cur = c1; cur < c2;) {
      gint first = src->cur_pgc->cell_playback[cur].first_sector;
      gint last = src->cur_pgc->cell_playback[cur].last_sector;
      GST_DEBUG_OBJECT (src, "Cell %d sector bounds: %d %d", cur, first, last);
      cur = next;
      if (src->cur_pgc->cell_playback[cur].block_type == BLOCK_TYPE_ANGLE_BLOCK)
        cur += angle;
      next = gst_dvd_read_src_get_next_cell (src, src->cur_pgc, cur);
      /* seeking to 0 should end up at first chapter in any case */
      if ((seek_to >= first && seek_to <= last) || (seek_to == 0 && i == 0)) {
        GST_DEBUG_OBJECT (src, "Seek target found in chapter %d", i);
        chapter = i;
        goto done;
      }
    }
  }

  GST_DEBUG_OBJECT (src, "Seek to sector %u failed", seek_to);

  return FALSE;

done:
  {
    /* so chapter $chapter and cell $cur contain our sector
     * of interest. Let's go there! */
    GST_INFO_OBJECT (src, "Seek succeeded, going to chapter %u, cell %u",
        chapter + 1, cur);

    gst_dvd_read_src_goto_chapter (src, chapter);
    src->cur_cell = cur;
    src->next_cell = next;
    src->new_cell = FALSE;
    src->cur_pack = seek_to;

    return TRUE;
  }
}


/*** URI interface ***/

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

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

  return protocols;
}

static gchar *
gst_dvd_read_src_uri_get_uri (GstURIHandler * handler)
{
  GstDvdReadSrc *src = GST_DVD_READ_SRC (handler);
  gchar *uri;

  GST_OBJECT_LOCK (src);
  uri = g_strdup_printf ("dvd://%d,%d,%d", src->uri_title, src->uri_chapter,
      src->uri_angle);
  GST_OBJECT_UNLOCK (src);

  return uri;
}

static gboolean
gst_dvd_read_src_uri_set_uri (GstURIHandler * handler, const gchar * uri,
    GError ** error)
{
  GstDvdReadSrc *src = GST_DVD_READ_SRC (handler);

  /* parse out the new t/c/a and seek to them */
  {
    gchar *location = NULL;
    gchar **strs;
    gchar **strcur;
    gint pos = 0;

    location = gst_uri_get_location (uri);

    GST_OBJECT_LOCK (src);

    src->uri_title = 1;
    src->uri_chapter = 1;
    src->uri_angle = 1;

    if (!location)
      goto empty_location;

    strcur = strs = g_strsplit (location, ",", 0);
    while (strcur && *strcur) {
      gint val;

      if (!sscanf (*strcur, "%d", &val))
        break;

      if (val <= 0) {
        g_warning ("Invalid value %d in URI '%s'. Must be 1 or greater",
            val, location);
        break;
      }

      switch (pos) {
        case 0:
          src->uri_title = val;
          break;
        case 1:
          src->uri_chapter = val;
          break;
        case 2:
          src->uri_angle = val;
          break;
      }

      strcur++;
      pos++;
    }

    if (pos > 0 && GST_OBJECT_FLAG_IS_SET (src, GST_BASE_SRC_FLAG_STARTED)) {
      src->title = src->uri_title - 1;
      src->chapter = src->uri_chapter - 1;
      src->angle = src->uri_angle - 1;
      src->new_seek = TRUE;
    }

    g_strfreev (strs);
    g_free (location);

  empty_location:

    GST_OBJECT_UNLOCK (src);
  }

  return TRUE;
}

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

  iface->get_type = gst_dvd_read_src_uri_get_type;
  iface->get_protocols = gst_dvd_read_src_uri_get_protocols;
  iface->get_uri = gst_dvd_read_src_uri_get_uri;
  iface->set_uri = gst_dvd_read_src_uri_set_uri;
}

static gboolean
plugin_init (GstPlugin * plugin)
{
  GST_DEBUG_CATEGORY_INIT (gstgst_dvd_read_src_debug, "dvdreadsrc", 0,
      "DVD reader element based on dvdreadsrc");

#ifdef ENABLE_NLS
  GST_DEBUG ("binding text domain %s to locale dir %s", GETTEXT_PACKAGE,
      LOCALEDIR);
  bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
#endif /* ENABLE_NLS */

  if (!gst_element_register (plugin, "dvdreadsrc", GST_RANK_NONE,
          GST_TYPE_DVD_READ_SRC)) {
    return FALSE;
  }

  return TRUE;
}

GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
    GST_VERSION_MINOR,
    dvdread,
    "Access a DVD with dvdread",
    plugin_init, VERSION, "GPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN);
