/* 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

#include "_stdint.h"

#include <stdio.h>
#include <stdlib.h>
#include <unistd.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_pad_template (gstelement_class,
      gst_static_pad_template_get (&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);
