/* 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_STICKY, 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);
