/* GStreamer
 * Copyright (C) 2008-2009 Jan Schmidt <thaytan@noraisin.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 <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <gmodule.h>
#include <gst/gst.h>
#include <gst/glib-compat-private.h>
#include <gst/gst-i18n-plugin.h>
#include <gst/video/video.h>
#include <gst/video/navigation.h>
#include <gst/tag/tag.h>

#include "resindvdsrc.h"

GST_DEBUG_CATEGORY_STATIC (rsndvdsrc_debug);
#define GST_CAT_DEFAULT rsndvdsrc_debug

#define DEFAULT_DEVICE "/dev/dvd"
#define DEFAULT_FASTSTART TRUE
#define DEFAULT_LANG "en"

#define GST_FLOW_WOULD_BLOCK GST_FLOW_CUSTOM_SUCCESS

#define CLOCK_BASE 9LL
#define CLOCK_FREQ CLOCK_BASE * 10000

#define MPEGTIME_TO_GSTTIME(time) (gst_util_uint64_scale ((time), \
            GST_MSECOND/10, CLOCK_BASE))
#define GSTTIME_TO_MPEGTIME(time) (gst_util_uint64_scale ((time), \
            CLOCK_BASE, GST_MSECOND/10))

typedef enum
{
  RSN_NAV_RESULT_NONE,
  RSN_NAV_RESULT_HIGHLIGHT,
  RSN_NAV_RESULT_BRANCH,
  RSN_NAV_RESULT_BRANCH_AND_HIGHLIGHT
} RsnNavResult;

typedef enum
{
  RSN_BTN_NONE = 0x00,
  RSN_BTN_LEFT = 0x01,
  RSN_BTN_RIGHT = 0x02,
  RSN_BTN_UP = 0x04,
  RSN_BTN_DOWN = 0x08
} RsnBtnMask;

enum
{
  /* FILL ME */
  LAST_SIGNAL
};

enum
{
  ARG_0,
  ARG_DEVICE,
  ARG_FASTSTART
};

typedef struct
{
  GstBuffer *buffer;
  GstClockTime ts;
  GstClockTime running_ts;
} RsnDvdPendingNav;

static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    // GST_STATIC_CAPS ("video/mpeg,mpegversion=2,systemstream=true")
    GST_STATIC_CAPS ("application/x-resin-dvd")
    );

/* Private seek format for private flushing */
static GstFormat rsndvd_format;
/* Title/chapter formats */
static GstFormat title_format;
static GstFormat chapter_format;

static void rsn_dvdsrc_register_extra (GType rsn_dvdsrc_type);

#define rsn_dvdsrc_parent_class parent_class
G_DEFINE_TYPE_EXTENDED (resinDvdSrc, rsn_dvdsrc, GST_TYPE_BASE_SRC,
    0, rsn_dvdsrc_register_extra (g_define_type_id));

static gboolean read_vts_info (resinDvdSrc * src);

static void rsn_dvdsrc_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void rsn_dvdsrc_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);

static void rsn_dvdsrc_finalize (GObject * object);

static gboolean rsn_dvdsrc_start (GstBaseSrc * bsrc);
static gboolean rsn_dvdsrc_stop (GstBaseSrc * bsrc);
static gboolean rsn_dvdsrc_unlock (GstBaseSrc * bsrc);
static gboolean rsn_dvdsrc_unlock_stop (GstBaseSrc * bsrc);

static gboolean rsn_dvdsrc_is_seekable (GstBaseSrc * bsrc);
static gboolean rsn_dvdsrc_prepare_seek (GstBaseSrc * bsrc,
    GstEvent * event, GstSegment * segment);
static gboolean rsn_dvdsrc_do_seek (GstBaseSrc * bsrc, GstSegment * segment);
static GstStateChangeReturn rsn_dvdsrc_change_state (GstElement * element,
    GstStateChange transition);

static void rsn_dvdsrc_prepare_spu_stream_event (resinDvdSrc * src,
    guint8 logical_stream, guint8 phys_stream, gboolean forced_only);
static void rsn_dvdsrc_prepare_audio_stream_event (resinDvdSrc * src,
    guint8 logical_stream, guint8 phys_stream);
static gboolean rsn_dvdsrc_prepare_streamsinfo_event (resinDvdSrc * src);
static void rsn_dvdsrc_prepare_clut_change_event (resinDvdSrc * src,
    const guint32 * clut);
static void rsn_dvdsrc_update_highlight (resinDvdSrc * src);

static void rsn_dvdsrc_enqueue_nav_block (resinDvdSrc * src,
    GstBuffer * nav_buf, GstClockTime ts);
static void rsn_dvdsrc_activate_nav_block (resinDvdSrc * src,
    GstBuffer * nav_buf);
static void rsn_dvdsrc_clear_nav_blocks (resinDvdSrc * src);
static void rsn_dvdsrc_check_nav_blocks (resinDvdSrc * src);
static void rsn_dvdsrc_schedule_nav_cb (resinDvdSrc * src,
    RsnDvdPendingNav * next_nav);

static GstFlowReturn rsn_dvdsrc_create (GstBaseSrc * bsrc, guint64 offset,
    guint length, GstBuffer ** buf);
static gboolean rsn_dvdsrc_src_event (GstBaseSrc * basesrc, GstEvent * event);
static gboolean rsn_dvdsrc_src_query (GstBaseSrc * basesrc, GstQuery * query);

static GstClockTime ifotime_to_gsttime (dvd_time_t * ifo_time);
static void rsn_dvdsrc_send_commands_changed (resinDvdSrc * src);

static GstClockTime
ifotime_to_gsttime (dvd_time_t * ifo_time)
{
  GstClockTime ts;
  guint frames;

  ts = 36000 * GST_SECOND * ((ifo_time->hour & 0xf0) >> 4);
  ts += 3600 * GST_SECOND * (ifo_time->hour & 0x0f);
  ts += 600 * GST_SECOND * ((ifo_time->minute & 0xf0) >> 4);
  ts += 60 * GST_SECOND * (ifo_time->minute & 0x0f);
  ts += 10 * GST_SECOND * ((ifo_time->second & 0xf0) >> 4);
  ts += GST_SECOND * (ifo_time->second & 0x0f);

  frames = ((ifo_time->frame_u >> 4) & 0x3) * 10;
  frames += (ifo_time->frame_u & 0xf);

  if (ifo_time->frame_u & 0x80)
    ts += GST_SECOND * frames / 30;
  else
    ts += GST_SECOND * frames / 25;

  return ts;
}

static void
rsn_dvdsrc_register_extra (GType rsn_dvdsrc_type)
{
  GST_DEBUG_CATEGORY_INIT (rsndvdsrc_debug, "rsndvdsrc", 0,
      "Resin DVD source element based on libdvdnav");

  rsndvd_format = gst_format_register ("rsndvdsrc-internal",
      "private Resin DVD src format");

  title_format = gst_format_register ("title", "DVD title format");
  chapter_format = gst_format_register ("chapter", "DVD chapter format");
}

static void
rsn_dvdsrc_class_init (resinDvdSrcClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
  GstBaseSrcClass *gstbasesrc_class;

  gobject_class = (GObjectClass *) klass;
  gstelement_class = (GstElementClass *) klass;
  gstbasesrc_class = GST_BASE_SRC_CLASS (klass);

  gobject_class->finalize = rsn_dvdsrc_finalize;
  gobject_class->set_property = rsn_dvdsrc_set_property;
  gobject_class->get_property = rsn_dvdsrc_get_property;

  gstelement_class->change_state = rsn_dvdsrc_change_state;

  gstbasesrc_class->start = GST_DEBUG_FUNCPTR (rsn_dvdsrc_start);
  gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (rsn_dvdsrc_stop);
  gstbasesrc_class->unlock = GST_DEBUG_FUNCPTR (rsn_dvdsrc_unlock);
  gstbasesrc_class->unlock_stop = GST_DEBUG_FUNCPTR (rsn_dvdsrc_unlock_stop);
  gstbasesrc_class->event = GST_DEBUG_FUNCPTR (rsn_dvdsrc_src_event);
  gstbasesrc_class->query = GST_DEBUG_FUNCPTR (rsn_dvdsrc_src_query);
  gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (rsn_dvdsrc_is_seekable);
  gstbasesrc_class->prepare_seek_segment =
      GST_DEBUG_FUNCPTR (rsn_dvdsrc_prepare_seek);
  gstbasesrc_class->do_seek = GST_DEBUG_FUNCPTR (rsn_dvdsrc_do_seek);

  gstbasesrc_class->create = GST_DEBUG_FUNCPTR (rsn_dvdsrc_create);

  g_object_class_install_property (gobject_class, ARG_DEVICE,
      g_param_spec_string ("device", "Device", "DVD device location",
          NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, ARG_FASTSTART,
      g_param_spec_boolean ("fast-start", "Fast start",
          "Skip straight to the DVD menu on start", DEFAULT_FASTSTART,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&src_factory));
  gst_element_class_set_static_metadata (gstelement_class, "Resin DVD Src",
      "Source/DVD", "DVD source element", "Jan Schmidt <thaytan@noraisin.net>");
}

static void
rsn_dvdsrc_init (resinDvdSrc * rsndvdsrc)
{
  const gchar *envvar;

  envvar = g_getenv ("DVDFASTSTART");
  if (envvar)
    rsndvdsrc->faststart = (strcmp (envvar, "0") && strcmp (envvar, "no"));
  else
    rsndvdsrc->faststart = DEFAULT_FASTSTART;

  rsndvdsrc->device = g_strdup (DEFAULT_DEVICE);
  rsndvdsrc->dvd_lock = g_mutex_new ();
  rsndvdsrc->branch_lock = g_mutex_new ();
  rsndvdsrc->branching = FALSE;
  rsndvdsrc->still_cond = g_cond_new ();

  gst_base_src_set_format (GST_BASE_SRC (rsndvdsrc), GST_FORMAT_TIME);
}

static void
rsn_dvdsrc_finalize (GObject * object)
{
  resinDvdSrc *src = RESINDVDSRC (object);

  g_mutex_free (src->dvd_lock);
  g_mutex_free (src->branch_lock);
  g_cond_free (src->still_cond);
  g_free (src->device);

  gst_buffer_replace (&src->alloc_buf, NULL);
  gst_buffer_replace (&src->next_buf, NULL);

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

static gboolean
rsn_dvdsrc_unlock (GstBaseSrc * bsrc)
{
  resinDvdSrc *src = RESINDVDSRC (bsrc);

  g_mutex_lock (src->branch_lock);
  src->branching = TRUE;
  g_cond_broadcast (src->still_cond);
  g_mutex_unlock (src->branch_lock);

  return TRUE;
}

static gboolean
rsn_dvdsrc_unlock_stop (GstBaseSrc * bsrc)
{
  resinDvdSrc *src = RESINDVDSRC (bsrc);

  g_mutex_lock (src->branch_lock);
  src->branching = FALSE;
  g_mutex_unlock (src->branch_lock);

  return TRUE;
}

static void
rsn_dvdsrc_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  resinDvdSrc *src = RESINDVDSRC (object);

  switch (prop_id) {
    case ARG_DEVICE:
      GST_OBJECT_LOCK (src);
      g_free (src->device);
      if (g_value_get_string (value) == NULL)
        src->device = g_strdup (DEFAULT_DEVICE);
      else
        src->device = g_value_dup_string (value);
      GST_OBJECT_UNLOCK (src);
      break;
    case ARG_FASTSTART:
      GST_OBJECT_LOCK (src);
      src->faststart = g_value_get_boolean (value);
      GST_OBJECT_UNLOCK (src);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
rsn_dvdsrc_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  resinDvdSrc *src = RESINDVDSRC (object);

  switch (prop_id) {
    case ARG_DEVICE:
      GST_OBJECT_LOCK (src);
      g_value_set_string (value, src->device);
      GST_OBJECT_UNLOCK (src);
      break;
    case ARG_FASTSTART:
      GST_OBJECT_LOCK (src);
      g_value_set_boolean (value, src->faststart);
      GST_OBJECT_UNLOCK (src);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static gboolean
rsn_dvdsrc_start (GstBaseSrc * bsrc)
{
  resinDvdSrc *src = RESINDVDSRC (bsrc);
  const gchar *const *langs, *const *cur;
  const char *disc_name;
  gchar lang[8];

  g_mutex_lock (src->dvd_lock);
  if (!read_vts_info (src)) {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
        (_("Could not read title information for DVD.")), GST_ERROR_SYSTEM);
    goto fail;
  }

  if (dvdnav_open (&src->dvdnav, src->device) != DVDNAV_STATUS_OK) {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
        (_("Failed to open DVD device '%s'."), src->device));
    goto fail;
  }

  if (dvdnav_set_PGC_positioning_flag (src->dvdnav, 1) != DVDNAV_STATUS_OK) {
    GST_ELEMENT_ERROR (src, LIBRARY, FAILED,
        (_("Failed to set PGC based seeking.")), GST_ERROR_SYSTEM);
    goto fail;
  }

  /* Attempt to set DVD menu, audio and spu languages */
  langs = g_get_language_names ();
  strncpy (lang, DEFAULT_LANG, 8);
  for (cur = langs; *cur != NULL; cur++) {
    /* Look for a 2 char iso-639 lang */
    if (strlen (*cur) == 2) {
      strncpy (lang, *cur, 8);
      break;
    }
  }
  /* Set the user's preferred language */
  dvdnav_menu_language_select (src->dvdnav, lang);
  dvdnav_audio_language_select (src->dvdnav, lang);
  dvdnav_spu_language_select (src->dvdnav, lang);

  if (src->faststart) {
    if (dvdnav_title_play (src->dvdnav, 1) != DVDNAV_STATUS_OK ||
        (dvdnav_menu_call (src->dvdnav, DVD_MENU_Title) != DVDNAV_STATUS_OK &&
            dvdnav_menu_call (src->dvdnav,
                DVD_MENU_Root) != DVDNAV_STATUS_OK)) {
      /* Fast start failed. Do normal start */
      dvdnav_reset (src->dvdnav);
    }
  }

  /* Get disc name and convert to UTF-8 */
  g_free (src->disc_name);
  dvdnav_get_title_string (src->dvdnav, &disc_name);
  if (disc_name != NULL && *disc_name != '\0')
    src->disc_name = gst_tag_freeform_string_to_utf8 (disc_name, -1, NULL);
  else
    src->disc_name = NULL;

  src->first_seek = TRUE;
  src->running = TRUE;
  src->branching = FALSE;
  src->discont = TRUE;
  src->need_segment = TRUE;
  src->need_tag_update = TRUE;

  src->cur_position = GST_CLOCK_TIME_NONE;
  src->pgc_duration = GST_CLOCK_TIME_NONE;
  src->cur_start_ts = GST_CLOCK_TIME_NONE;
  src->cur_end_ts = GST_CLOCK_TIME_NONE;
  src->cur_vobu_base_ts = GST_CLOCK_TIME_NONE;

  src->vts_n = 0;
  src->in_menu = FALSE;
  src->title_n = -1;
  src->part_n = -1;

  src->active_button = -1;
  src->cur_btn_mask = RSN_BTN_NONE;

  src->angles_changed = FALSE;
  src->n_angles = 0;
  src->cur_angle = 0;

  src->commands_changed = TRUE;

  src->cur_spu_phys_stream = -1;
  src->cur_spu_forced_only = FALSE;
  memset (src->cur_clut, 0, sizeof (guint32) * 16);
  src->cur_audio_phys_stream = -1;

  g_mutex_unlock (src->dvd_lock);

  return TRUE;

fail:
  if (src->dvdnav) {
    dvdnav_close (src->dvdnav);
    src->dvdnav = NULL;
  }
  g_mutex_unlock (src->dvd_lock);
  return FALSE;
}

/* Use libdvdread to read and cache info from the IFO file about
 * streams in each VTS */
static gboolean
read_vts_info (resinDvdSrc * src)
{
  gint n_vts;

  if (src->vts_attrs) {
    g_array_free (src->vts_attrs, TRUE);
    src->vts_attrs = NULL;
  }

  if (src->dvdread)
    DVDClose (src->dvdread);

  src->dvdread = DVDOpen (src->device);
  if (src->dvdread == NULL)
    return FALSE;

  if (!(src->vmg_file = ifoOpen (src->dvdread, 0))) {
    GST_ERROR ("Can't open VMG ifo");
    return FALSE;
  }
  if (!src->vmg_file->vts_atrt) {
    GST_INFO ("No vts_atrt - odd, but apparently OK");
    g_array_set_size (src->vts_attrs, 0);
    src->vts_attrs = NULL;
    return TRUE;
  }
  n_vts = src->vmg_file->vts_atrt->nr_of_vtss;
  memcpy (&src->vmgm_attr, src->vmg_file->vmgi_mat, sizeof (vmgi_mat_t));

  GST_DEBUG ("Reading IFO info for %d VTSs", n_vts);
  src->vts_attrs =
      g_array_sized_new (FALSE, TRUE, sizeof (vtsi_mat_t), n_vts + 1);
  if (!src->vts_attrs)
    return FALSE;
  g_array_set_size (src->vts_attrs, n_vts + 1);

  return TRUE;
}

static vtsi_mat_t *
get_vts_attr (resinDvdSrc * src, gint n)
{
  vtsi_mat_t *vts_attr;

  if (src->vts_attrs == NULL || n >= src->vts_attrs->len) {
    if (src->vts_attrs)
      GST_ERROR_OBJECT (src, "No stream info for VTS %d (have %d)", n,
          src->vts_attrs->len);
    else
      GST_ERROR_OBJECT (src, "No stream info");
    return NULL;
  }

  vts_attr = &g_array_index (src->vts_attrs, vtsi_mat_t, src->vts_n);

  /* Check if we have read this VTS ifo yet */
  if (vts_attr->vtsm_vobs == 0) {
    ifo_handle_t *ifo = ifoOpen (src->dvdread, n);

    if (!ifo) {
      GST_ERROR ("Can't open VTS %d", n);
      return NULL;
    }

    GST_DEBUG ("VTS %d, Menu has %d audio %d subpictures. "
        "Title has %d and %d", n,
        ifo->vtsi_mat->nr_of_vtsm_audio_streams,
        ifo->vtsi_mat->nr_of_vtsm_subp_streams,
        ifo->vtsi_mat->nr_of_vts_audio_streams,
        ifo->vtsi_mat->nr_of_vts_subp_streams);

    memcpy (&g_array_index (src->vts_attrs, vtsi_mat_t, n),
        ifo->vtsi_mat, sizeof (vtsi_mat_t));

    ifoClose (ifo);
  };

  return vts_attr;
}

static gboolean
rsn_dvdsrc_stop (GstBaseSrc * bsrc)
{
  resinDvdSrc *src = RESINDVDSRC (bsrc);
  gboolean ret = TRUE;
  GstMessage *mouse_over_msg = NULL;

  g_mutex_lock (src->dvd_lock);

  if (src->nav_clock_id) {
    gst_clock_id_unschedule (src->nav_clock_id);
    gst_clock_id_unref (src->nav_clock_id);
    src->nav_clock_id = NULL;
  }
  rsn_dvdsrc_clear_nav_blocks (src);
  src->have_pci = FALSE;

  if (src->was_mouse_over) {
    mouse_over_msg =
        gst_navigation_message_new_mouse_over ((GstObject *) src, FALSE);
    src->was_mouse_over = FALSE;
  }

  /* Clear any allocated output buffer */
  gst_buffer_replace (&src->alloc_buf, NULL);
  gst_buffer_replace (&src->next_buf, NULL);
  src->running = FALSE;

  if (src->streams_event) {
    gst_event_unref (src->streams_event);
    src->streams_event = NULL;
  }
  if (src->clut_event) {
    gst_event_unref (src->clut_event);
    src->clut_event = NULL;
  }
  if (src->spu_select_event) {
    gst_event_unref (src->spu_select_event);
    src->spu_select_event = NULL;
  }
  if (src->audio_select_event) {
    gst_event_unref (src->audio_select_event);
    src->audio_select_event = NULL;
  }
  if (src->highlight_event) {
    gst_event_unref (src->highlight_event);
    src->highlight_event = NULL;
  }

  g_free (src->disc_name);
  src->disc_name = NULL;

  if (src->dvdnav) {
    if (dvdnav_close (src->dvdnav) != DVDNAV_STATUS_OK) {
      GST_ELEMENT_ERROR (src, RESOURCE, CLOSE, (NULL),
          ("dvdnav_close failed: %s", dvdnav_err_to_string (src->dvdnav)));
      ret = FALSE;
    }
    src->dvdnav = NULL;
  }

  if (src->vmg_file) {
    ifoClose (src->vmg_file);
    src->vmg_file = NULL;
  }
  if (src->vts_file) {
    ifoClose (src->vts_file);
    src->vts_file = NULL;
  }
  if (src->dvdread) {
    DVDClose (src->dvdread);
    src->dvdread = NULL;
  }

  g_mutex_unlock (src->dvd_lock);

  if (mouse_over_msg)
    gst_element_post_message (GST_ELEMENT_CAST (src), mouse_over_msg);
  return ret;
}

/* handle still events. Call with dvd_lock */
static gboolean
rsn_dvdsrc_do_still (resinDvdSrc * src, int duration)
{
  GstEvent *still_event;
  GstEvent *hl_event;
  gboolean cmds_changed;
  GstEvent *seg_event;
  GstSegment *segment = &(GST_BASE_SRC (src)->segment);

  if (src->in_still_state == FALSE) {
    GST_DEBUG_OBJECT (src, "**** Start STILL FRAME. Duration %d ****",
        duration);

    if (duration == 255)
      src->still_time_remaining = GST_CLOCK_TIME_NONE;
    else
      src->still_time_remaining = GST_SECOND * duration;

    /* Send a close-segment event, and a still-frame start
     * event, then sleep */
    still_event = gst_video_event_new_still_frame (TRUE);

    segment->stop = segment->position = src->cur_end_ts;
    GST_LOG_OBJECT (src, "Segment position now %" GST_TIME_FORMAT,
        GST_TIME_ARGS (segment->position));

    seg_event = gst_event_new_segment (segment);

    /* Grab any pending highlight event to send too */
    hl_event = src->highlight_event;
    src->highlight_event = NULL;
    cmds_changed = src->commands_changed;
    src->commands_changed = FALSE;

    /* Now, send the events. We need to drop the dvd lock while doing so,
     * and then check after if we got flushed */
    g_mutex_unlock (src->dvd_lock);
    gst_pad_push_event (GST_BASE_SRC_PAD (src), still_event);
    gst_pad_push_event (GST_BASE_SRC_PAD (src), seg_event);
    if (hl_event) {
      GST_LOG_OBJECT (src, "Sending highlight event before still");
      gst_pad_push_event (GST_BASE_SRC_PAD (src), hl_event);
    }
    if (cmds_changed)
      rsn_dvdsrc_send_commands_changed (src);

    g_mutex_lock (src->dvd_lock);

    g_mutex_lock (src->branch_lock);

    src->in_still_state = TRUE;
  } else {
    GST_DEBUG_OBJECT (src,
        "Re-entering still wait with %" GST_TIME_FORMAT " remaining",
        GST_TIME_ARGS (src->still_time_remaining));
    g_mutex_lock (src->branch_lock);
  }

  if (src->branching) {
    GST_INFO_OBJECT (src, "Branching - aborting still");
    g_mutex_unlock (src->branch_lock);
    return TRUE;
  }

  if (duration == 255) {
    /*
     * The only way to get woken from this still is by a flushing
     * seek or a user action. Either one will clear the still, so
     * don't skip it
     */
    src->need_segment = TRUE;

    g_mutex_unlock (src->dvd_lock);
    GST_LOG_OBJECT (src, "Entering cond_wait still");
    g_cond_wait (src->still_cond, src->branch_lock);
    GST_LOG_OBJECT (src, "cond_wait still over, branching = %d",
        src->branching);

    if (src->branching) {
      g_mutex_unlock (src->branch_lock);
      g_mutex_lock (src->dvd_lock);
      return TRUE;
    }
    src->in_still_state = FALSE;

    g_mutex_unlock (src->branch_lock);
    g_mutex_lock (src->dvd_lock);
  } else {
    GTimeVal end_time;
    gboolean was_signalled;

    if (src->still_time_remaining > 0) {
      g_get_current_time (&end_time);
      g_time_val_add (&end_time, src->still_time_remaining / GST_USECOND);

      /* Implement timed stills by sleeping, possibly
       * in multiple steps if we get paused/unpaused */
      g_mutex_unlock (src->dvd_lock);
      GST_LOG_OBJECT (src, "cond_timed_wait still for %d sec", duration);
      was_signalled =
          g_cond_timed_wait (src->still_cond, src->branch_lock, &end_time);
      was_signalled |= src->branching;

      g_mutex_unlock (src->branch_lock);
      g_mutex_lock (src->dvd_lock);

      if (was_signalled) {
        /* Signalled - must be flushing */
        GTimeVal cur_time;
        GstClockTimeDiff remain;

        g_get_current_time (&cur_time);
        remain =
            (end_time.tv_sec - cur_time.tv_sec) * GST_SECOND +
            (end_time.tv_usec - cur_time.tv_usec) * GST_USECOND;
        if (remain < 0)
          src->still_time_remaining = 0;
        else
          src->still_time_remaining = remain;

        GST_LOG_OBJECT (src,
            "cond_timed_wait still aborted by signal with %" GST_TIME_FORMAT
            " remaining. branching = %d",
            GST_TIME_ARGS (src->still_time_remaining), src->branching);

        return TRUE;
      }
    }

    /* Else timed out, end the still */
    GST_DEBUG_OBJECT (src,
        "Timed still of %d secs over, calling dvdnav_still_skip", duration);

    if (dvdnav_still_skip (src->dvdnav) != DVDNAV_STATUS_OK) {
      return FALSE;
    }

    /* Tell downstream the still is over.
     * We only do this if the still isn't interrupted: */
    still_event = gst_video_event_new_still_frame (FALSE);

    /* If the segment was too short in a timed still, it may need extending */
    if (segment->position < segment->start + GST_SECOND * duration) {
      segment->position = segment->start + (GST_SECOND * duration);
      if (segment->stop != -1 && segment->position > segment->stop)
        segment->stop = segment->position;

      GST_LOG_OBJECT (src, "Extended segment position to %" GST_TIME_FORMAT,
          GST_TIME_ARGS (segment->position));
    }

    g_mutex_unlock (src->dvd_lock);
    gst_pad_push_event (GST_BASE_SRC_PAD (src), still_event);
    g_mutex_lock (src->dvd_lock);
  }

  return TRUE;
}

static pgc_t *
get_current_pgc (resinDvdSrc * src)
{
  gint title, part, pgc_n;
  gint32 vts_ttn;
  pgc_t *pgc;

  if (dvdnav_is_domain_fp (src->dvdnav)) {
    return src->vmg_file->first_play_pgc;
  }

  if (src->vts_n == 0 || src->in_menu) {
    /* FIXME: look up current menu PGC */
    return NULL;
  }

  if (dvdnav_current_title_info (src->dvdnav, &title, &part) !=
      DVDNAV_STATUS_OK)
    return NULL;

  /* To find the right PGC, we need the title number within this VTS (vts_ttn)
   * from the VMG tt_srpt table... */
  if (title < 1 || title > src->vmg_file->tt_srpt->nr_of_srpts)
    return NULL;

  /* We must be in the correct VTS for any of this to succeed... */
  if (src->vts_n != src->vmg_file->tt_srpt->title[title - 1].title_set_nr)
    return NULL;

  /* We must also be in the VTS domain to use the tmap table */
  if (src->vts_n == 0)
    return NULL;

  vts_ttn = src->vmg_file->tt_srpt->title[title - 1].vts_ttn;

  if (vts_ttn < 1 || vts_ttn > src->vts_file->vts_ptt_srpt->nr_of_srpts)
    return NULL;

  if (src->vts_file->vts_ptt_srpt->title[vts_ttn - 1].nr_of_ptts == 0)
    return NULL;

  pgc_n = src->vts_file->vts_ptt_srpt->title[vts_ttn - 1].ptt[0].pgcn;
  if (pgc_n > src->vts_file->vts_pgcit->nr_of_pgci_srp)
    return NULL;

  pgc = src->vts_file->vts_pgcit->pgci_srp[pgc_n - 1].pgc;

  return pgc;
}

static GstTagList *
update_title_info (resinDvdSrc * src, gboolean force)
{
  gint n_angles, cur_agl;
  gint title_n, part_n;

  if (dvdnav_get_angle_info (src->dvdnav, &cur_agl,
          &n_angles) == DVDNAV_STATUS_OK && src->n_angles != n_angles) {
    /* Make sure we send an angles-changed message soon */
    src->angles_changed = TRUE;
  }

  if (dvdnav_current_title_info (src->dvdnav, &title_n,
          &part_n) != DVDNAV_STATUS_OK) {
    if (!src->in_menu)
      return NULL;              /* Can't update now */
    /* Must be in the first play sequence */
    title_n = -1;
    part_n = 0;
  }

  if (title_n != src->title_n || part_n != src->part_n ||
      src->n_angles != n_angles || src->cur_angle != cur_agl || force) {
    gchar *title_str = NULL;

    src->title_n = title_n;
    src->part_n = part_n;
    src->n_angles = n_angles;
    src->cur_angle = cur_agl;

    if (title_n == 0) {
      /* In a menu */
      title_str = g_strdup ("DVD Menu");
    } else if (title_n > 0) {
      /* In a title */
      if (n_angles > 1) {
        title_str = g_strdup_printf ("Title %i, Chapter %i, Angle %i of %i",
            title_n, part_n, cur_agl, n_angles);

      } else {
        title_str = g_strdup_printf ("Title %i, Chapter %i", title_n, part_n);
      }
    }

    if (src->disc_name && src->disc_name[0]) {
      /* We have a name for this disc, publish it */
      if (title_str) {
        gchar *new_title_str =
            g_strdup_printf ("%s, %s", title_str, src->disc_name);
        g_free (title_str);
        title_str = new_title_str;
      } else {
        title_str = g_strdup (src->disc_name);
      }
    }
    if (title_str) {
      GstTagList *tags = gst_tag_list_new (GST_TAG_TITLE, title_str, NULL);
      g_free (title_str);
      return tags;
    }
  }

  return NULL;
}

/* we don't cache the result on purpose */
static gboolean
rsn_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
rsn_dvdsrc_step (resinDvdSrc * src, gboolean have_dvd_lock)
{
  GstFlowReturn ret = GST_FLOW_OK;
  dvdnav_status_t dvdnav_ret;
  gint event, len;
  GstMapInfo mmap;

  /* Allocate an output buffer if there isn't a pending one */
  if (src->alloc_buf == NULL)
    src->alloc_buf = gst_buffer_new_allocate (NULL, DVD_VIDEO_LB_LEN, NULL);

  gst_buffer_map (src->alloc_buf, &mmap, GST_MAP_WRITE);

  len = DVD_VIDEO_LB_LEN;

  dvdnav_ret = dvdnav_get_next_block (src->dvdnav, mmap.data, &event, &len);
  if (dvdnav_ret != DVDNAV_STATUS_OK)
    goto read_error;
  g_mutex_lock (src->branch_lock);
  if (src->branching)
    goto branching;
  g_mutex_unlock (src->branch_lock);

  switch (event) {
    case DVDNAV_BLOCK_OK:
      /* Data block that needs outputting */
      gst_buffer_unmap (src->alloc_buf, &mmap);
      src->next_buf = src->alloc_buf;
      src->alloc_buf = NULL;

      src->next_is_nav_block = FALSE;
      src->next_nav_ts = GST_CLOCK_TIME_NONE;
      src->in_still_state = FALSE;
      break;
    case DVDNAV_NAV_PACKET:
    {
      pci_t *pci = dvdnav_get_current_nav_pci (src->dvdnav);
      GstClockTime new_start_ptm = MPEGTIME_TO_GSTTIME (pci->pci_gi.vobu_s_ptm);
      GstClockTime new_end_ptm = MPEGTIME_TO_GSTTIME (pci->pci_gi.vobu_e_ptm);
      GstClockTimeDiff new_base_time = ifotime_to_gsttime (&pci->pci_gi.e_eltm);
      gboolean discont = FALSE;

      src->in_still_state = FALSE;

      if (new_start_ptm != src->cur_end_ts) {
        /* Hack because libdvdnav seems to lose a NAV packet during
         * angle block changes, triggering a false discont */
        GstClockTimeDiff diff = GST_CLOCK_DIFF (src->cur_end_ts, new_start_ptm);
        if (src->cur_end_ts == GST_CLOCK_TIME_NONE || diff > 2 * GST_SECOND ||
            diff < 0) {
          discont = TRUE;
          GST_DEBUG_OBJECT (src, "Discont NAV packet start TS %" GST_TIME_FORMAT
              " != end TS %" GST_TIME_FORMAT,
              GST_TIME_ARGS (new_start_ptm), GST_TIME_ARGS (src->cur_end_ts));
        }
      }

      GST_LOG_OBJECT (src, "NAV packet start TS %" GST_TIME_FORMAT
          " end TS %" GST_TIME_FORMAT " base %" G_GINT64_FORMAT " %s",
          GST_TIME_ARGS (new_start_ptm), GST_TIME_ARGS (new_end_ptm),
          new_base_time, discont ? "discont" : "");

#if 0
      g_print ("NAV packet start TS %" GST_TIME_FORMAT
          " end TS %" GST_TIME_FORMAT " base %" G_GINT64_FORMAT " %s\n",
          GST_TIME_ARGS (new_start_ptm), GST_TIME_ARGS (new_end_ptm),
          new_base_time, discont ? "discont" : "");
#endif

      if (discont) {
        GST_DEBUG_OBJECT (src,
            "NAV packet discont: cur_end_ts %" GST_TIME_FORMAT " != "
            " vobu_start_ptm: %" GST_TIME_FORMAT " base %" GST_TIME_FORMAT,
            GST_TIME_ARGS (src->cur_end_ts),
            GST_TIME_ARGS (new_start_ptm), GST_TIME_ARGS (new_base_time));
        src->need_segment = TRUE;
      }

      src->cur_start_ts = new_start_ptm;
      src->cur_end_ts = new_end_ptm;
      src->cur_vobu_base_ts = new_base_time;

      /* NAV packet is also a data block that needs sending */
      gst_buffer_unmap (src->alloc_buf, &mmap);
      src->next_buf = src->alloc_buf;
      src->alloc_buf = NULL;

      if (!src->have_pci || pci->hli.hl_gi.hli_ss != 2) {
        /* Store the nav packet for activation at the right moment
         * if we don't have a packet yet or the info has changed (hli_ss != 2)
         */
        if (pci->hli.hl_gi.hli_s_ptm != 0)
          new_start_ptm = MPEGTIME_TO_GSTTIME (pci->hli.hl_gi.hli_s_ptm);

        src->next_is_nav_block = TRUE;
        src->next_nav_ts = new_start_ptm;
        GST_LOG_OBJECT (src, "Storing NAV pack with TS %" GST_TIME_FORMAT,
            GST_TIME_ARGS (src->next_nav_ts));
      } else {
        src->next_is_nav_block = FALSE;
        src->next_nav_ts = GST_CLOCK_TIME_NONE;
      }
      break;
    }
    case DVDNAV_STOP:
      /* End of the disc. EOS */
      dvdnav_reset (src->dvdnav);
      ret = GST_FLOW_EOS;
      break;
    case DVDNAV_STILL_FRAME:
    {
      dvdnav_still_event_t *info = (dvdnav_still_event_t *) mmap.data;

      if (!have_dvd_lock) {
        /* At a still frame but can't block, handle it later */
        return GST_FLOW_WOULD_BLOCK;
      }

      if (!rsn_dvdsrc_do_still (src, info->length))
        goto internal_error;

      g_mutex_lock (src->branch_lock);
      if (src->branching)
        goto branching;
      g_mutex_unlock (src->branch_lock);
      break;
    }
    case DVDNAV_WAIT:
      /* Drain out the queues so that the info on the screen matches
       * the VM state */
      if (have_dvd_lock) {
        /* FIXME: Drain out the queues, by sleeping on the clock or something */
        GST_LOG_OBJECT (src, "****** FIXME: WAIT for queues to drain *****");
      }
      if (dvdnav_wait_skip (src->dvdnav) != DVDNAV_STATUS_OK)
        goto internal_error;
      break;
    case DVDNAV_CELL_CHANGE:{
      dvdnav_cell_change_event_t *event =
          (dvdnav_cell_change_event_t *) mmap.data;
      GstMessage *message;

      src->pgc_duration = MPEGTIME_TO_GSTTIME (event->pgc_length);
      /* event->cell_start has the wrong time - it doesn't handle
       * multi-angle correctly (as of libdvdnav 4.1.3). The current_time()
       * calculates it correctly. */
      src->cur_position =
          MPEGTIME_TO_GSTTIME (dvdnav_get_current_time (src->dvdnav));

      GST_DEBUG_OBJECT (src,
          "CELL change dur now %" GST_TIME_FORMAT " position now %"
          GST_TIME_FORMAT, GST_TIME_ARGS (src->pgc_duration),
          GST_TIME_ARGS (src->cur_position));

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

      rsn_dvdsrc_prepare_streamsinfo_event (src);
      src->need_tag_update = TRUE;

      break;
    }
    case DVDNAV_SPU_CLUT_CHANGE:
      rsn_dvdsrc_prepare_clut_change_event (src, (const guint32 *) mmap.data);
      break;
    case DVDNAV_VTS_CHANGE:{
      dvdnav_vts_change_event_t *event =
          (dvdnav_vts_change_event_t *) mmap.data;

      if (dvdnav_is_domain_vmgm (src->dvdnav)) {
        src->vts_n = 0;
      } else {
        src->vts_n = event->new_vtsN;
        if (src->vts_file) {
          ifoClose (src->vts_file);
          src->vts_file = NULL;
        }
        src->vts_file = ifoOpen (src->dvdread, src->vts_n);
      }

      src->in_menu = !dvdnav_is_domain_vts (src->dvdnav);

      break;
    }
    case DVDNAV_AUDIO_STREAM_CHANGE:{
      dvdnav_audio_stream_change_event_t *event =
          (dvdnav_audio_stream_change_event_t *) mmap.data;

      rsn_dvdsrc_prepare_audio_stream_event (src,
          event->logical, event->physical);
      GST_DEBUG_OBJECT (src, "  physical: %d", event->physical);
      GST_DEBUG_OBJECT (src, "  logical: %d", event->logical);

      break;
    }
    case DVDNAV_SPU_STREAM_CHANGE:{
      dvdnav_spu_stream_change_event_t *event =
          (dvdnav_spu_stream_change_event_t *) mmap.data;
      gint phys_track = event->physical_wide & 0x1f;
      gboolean forced_only = (event->physical_wide & 0x80) ? TRUE : FALSE;

      rsn_dvdsrc_prepare_spu_stream_event (src, event->logical, phys_track,
          forced_only);

      GST_DEBUG_OBJECT (src, "  physical_wide: %x", event->physical_wide);
      GST_DEBUG_OBJECT (src, "  physical_letterbox: %x",
          event->physical_letterbox);
      GST_DEBUG_OBJECT (src, "  physical_pan_scan: %x",
          event->physical_pan_scan);
      GST_DEBUG_OBJECT (src, "  logical: %x", event->logical);
      break;
    }
    case DVDNAV_HIGHLIGHT:{
      GST_DEBUG_OBJECT (src, "highlight change event, button %d",
          ((dvdnav_highlight_event_t *) mmap.data)->buttonN);
      rsn_dvdsrc_update_highlight (src);
      break;
    }
    case DVDNAV_HOP_CHANNEL:
      GST_DEBUG_OBJECT (src, "Channel hop - User action");
      src->need_segment = TRUE;
      break;
    case DVDNAV_NOP:
      break;
    default:
      GST_WARNING_OBJECT (src, "Unknown dvdnav event %d", event);
      break;
  }
  if (src->alloc_buf) {
    gst_buffer_unmap (src->alloc_buf, &mmap);
  }

  if (src->highlight_event && have_dvd_lock && src->in_playing) {
    GstEvent *hl_event = src->highlight_event;

    src->highlight_event = NULL;
    g_mutex_unlock (src->dvd_lock);
    GST_DEBUG_OBJECT (src, "Sending highlight event - button %d",
        src->active_button);
    gst_pad_push_event (GST_BASE_SRC_PAD (src), hl_event);
    g_mutex_lock (src->dvd_lock);
  }

  return ret;

/* ERRORS */
read_error:
  {
    gst_buffer_unmap (src->alloc_buf, &mmap);
    if (!rsn_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.")),
          ("Failed to read next DVD block. Error: %s",
              dvdnav_err_to_string (src->dvdnav)));
    } else {
      GST_ELEMENT_ERROR (src, RESOURCE, READ, (_("Could not read DVD.")),
          ("Failed to read next DVD block. Error: %s",
              dvdnav_err_to_string (src->dvdnav)));
    }
    return GST_FLOW_ERROR;
  }
internal_error:
  {
    gst_buffer_unmap (src->alloc_buf, &mmap);
    GST_ELEMENT_ERROR (src, RESOURCE, READ, (_("Could not read DVD.")),
        ("Internal error processing DVD commands. Error: %s",
            dvdnav_err_to_string (src->dvdnav)));
    return GST_FLOW_ERROR;
  }
branching:
  {
    g_mutex_unlock (src->branch_lock);
    gst_buffer_unmap (src->alloc_buf, &mmap);
    return GST_FLOW_FLUSHING;
  }
}

/* Send app a bus message that the available commands have changed */
static void
rsn_dvdsrc_send_commands_changed (resinDvdSrc * src)
{
  GstMessage *cmds_msg =
      gst_navigation_message_new_commands_changed (GST_OBJECT_CAST (src));
  gst_element_post_message (GST_ELEMENT_CAST (src), cmds_msg);
}

static gboolean
rsn_dvdsrc_handle_cmds_query (resinDvdSrc * src, GstQuery * query)
{
  /* Expand this array if we have more commands in the future: */
  GstNavigationCommand cmds[16];
  gint n_cmds = 0;

  /* Fill out the standard set of commands we support */
  cmds[n_cmds++] = GST_NAVIGATION_COMMAND_DVD_MENU;
  cmds[n_cmds++] = GST_NAVIGATION_COMMAND_DVD_TITLE_MENU;
  cmds[n_cmds++] = GST_NAVIGATION_COMMAND_DVD_ROOT_MENU;
  cmds[n_cmds++] = GST_NAVIGATION_COMMAND_DVD_SUBPICTURE_MENU;
  cmds[n_cmds++] = GST_NAVIGATION_COMMAND_DVD_AUDIO_MENU;
  cmds[n_cmds++] = GST_NAVIGATION_COMMAND_DVD_ANGLE_MENU;
  cmds[n_cmds++] = GST_NAVIGATION_COMMAND_DVD_CHAPTER_MENU;

  g_mutex_lock (src->dvd_lock);

  /* Multiple angles available? */
  if (src->n_angles > 1) {
    cmds[n_cmds++] = GST_NAVIGATION_COMMAND_PREV_ANGLE;
    cmds[n_cmds++] = GST_NAVIGATION_COMMAND_NEXT_ANGLE;
  }

  /* Add button selection commands if we have them */
  if (src->active_button > 0) {
    /* We have a valid current button */
    cmds[n_cmds++] = GST_NAVIGATION_COMMAND_ACTIVATE;
  }
  /* Check for buttons in each direction */
  if (src->cur_btn_mask & RSN_BTN_LEFT)
    cmds[n_cmds++] = GST_NAVIGATION_COMMAND_LEFT;
  if (src->cur_btn_mask & RSN_BTN_RIGHT)
    cmds[n_cmds++] = GST_NAVIGATION_COMMAND_RIGHT;
  if (src->cur_btn_mask & RSN_BTN_UP)
    cmds[n_cmds++] = GST_NAVIGATION_COMMAND_UP;
  if (src->cur_btn_mask & RSN_BTN_DOWN)
    cmds[n_cmds++] = GST_NAVIGATION_COMMAND_DOWN;
  g_mutex_unlock (src->dvd_lock);

  gst_navigation_query_set_commandsv (query, n_cmds, cmds);

  return TRUE;
}

static gboolean
rsn_dvdsrc_handle_angles_query (resinDvdSrc * src, GstQuery * query)
{
  gint cur_agl, n_angles;
  gboolean res = FALSE;

  g_mutex_lock (src->dvd_lock);
  if (dvdnav_get_angle_info (src->dvdnav, &cur_agl,
          &n_angles) == DVDNAV_STATUS_OK) {
    gst_navigation_query_set_angles (query, cur_agl, n_angles);
    res = TRUE;
  }
  g_mutex_unlock (src->dvd_lock);

  return res;
}

static gboolean
rsn_dvdsrc_handle_navigation_query (resinDvdSrc * src,
    GstNavigationQueryType nq_type, GstQuery * query)
{
  gboolean res;

  GST_LOG_OBJECT (src, "Have Navigation query of type %d", nq_type);

  switch (nq_type) {
    case GST_NAVIGATION_QUERY_COMMANDS:
      res = rsn_dvdsrc_handle_cmds_query (src, query);
      break;
    case GST_NAVIGATION_QUERY_ANGLES:
      res = rsn_dvdsrc_handle_angles_query (src, query);
      break;
    default:
      res = FALSE;
  }

  return res;
}

static GstFlowReturn
rsn_dvdsrc_prepare_next_block (resinDvdSrc * src, gboolean have_dvd_lock)
{
  GstFlowReturn ret;

  /* If buffer already ready, return */
  if (src->next_buf)
    return GST_FLOW_OK;

  do {
    ret = rsn_dvdsrc_step (src, have_dvd_lock);
  }
  while (ret == GST_FLOW_OK && src->next_buf == NULL);

  if (ret == GST_FLOW_WOULD_BLOCK)
    ret = GST_FLOW_OK;

  return ret;
}

static GstFlowReturn
rsn_dvdsrc_create (GstBaseSrc * bsrc, guint64 offset,
    guint length, GstBuffer ** outbuf)
{
  resinDvdSrc *src = RESINDVDSRC (bsrc);
  GstSegment *segment = &(GST_BASE_SRC (src)->segment);
  GstFlowReturn ret;
  GstEvent *streams_event = NULL;
  GstEvent *clut_event = NULL;
  GstEvent *spu_select_event = NULL;
  GstEvent *audio_select_event = NULL;
  GstEvent *highlight_event = NULL;
  GstMessage *angles_msg = NULL;
  GstTagList *tags = NULL;
  gboolean cmds_changed = FALSE;

  *outbuf = NULL;

  g_mutex_lock (src->dvd_lock);
  ret = rsn_dvdsrc_prepare_next_block (src, TRUE);
  if (ret != GST_FLOW_OK) {
    g_mutex_unlock (src->dvd_lock);
    return ret;
  }

  streams_event = src->streams_event;
  src->streams_event = NULL;

  spu_select_event = src->spu_select_event;
  src->spu_select_event = NULL;

  audio_select_event = src->audio_select_event;
  src->audio_select_event = NULL;

  clut_event = src->clut_event;
  src->clut_event = NULL;

  if (src->angles_changed) {
    gint cur, agls;
    if (dvdnav_get_angle_info (src->dvdnav, &cur, &agls) == DVDNAV_STATUS_OK) {

      angles_msg =
          gst_navigation_message_new_angles_changed (GST_OBJECT_CAST (src),
          cur, agls);
    }
    src->angles_changed = FALSE;
  }

  cmds_changed = src->commands_changed;
  src->commands_changed = FALSE;

  if (src->need_tag_update) {
    tags = update_title_info (src, FALSE);
    src->need_tag_update = FALSE;
  }

  g_mutex_unlock (src->dvd_lock);

  /* Push in-band events now that we've dropped the dvd_lock, before
   * we change segment */
  if (streams_event) {
    GST_LOG_OBJECT (src, "Pushing stream layout event");
    gst_pad_push_event (GST_BASE_SRC_PAD (src), streams_event);
  }
  if (clut_event) {
    GST_LOG_OBJECT (src, "Pushing clut event");
    gst_pad_push_event (GST_BASE_SRC_PAD (src), clut_event);
  }
  /* Out of band events */
  if (spu_select_event) {
    GST_LOG_OBJECT (src, "Pushing spu_select event");
    gst_pad_push_event (GST_BASE_SRC_PAD (src), spu_select_event);
  }
  if (audio_select_event) {
    GST_LOG_OBJECT (src, "Pushing audio_select event");
    gst_pad_push_event (GST_BASE_SRC_PAD (src), audio_select_event);
  }

  if (src->need_segment) {
    /* Seamless segment update */
    GstClockTime elapsed_time = 0;

    if (src->cur_position != GST_CLOCK_TIME_NONE)
      elapsed_time += src->cur_position;
    if (src->cur_vobu_base_ts != GST_CLOCK_TIME_NONE)
      elapsed_time += src->cur_vobu_base_ts;

    GST_DEBUG_OBJECT (src,
        "Starting seamless segment update to %" GST_TIME_FORMAT " -> %"
        GST_TIME_FORMAT " VOBU %" GST_TIME_FORMAT " time %" GST_TIME_FORMAT,
        GST_TIME_ARGS (src->cur_start_ts), GST_TIME_ARGS (src->cur_end_ts),
        GST_TIME_ARGS (src->cur_vobu_base_ts), GST_TIME_ARGS (elapsed_time));

    gst_base_src_new_seamless_segment (GST_BASE_SRC (src),
        src->cur_start_ts, -1, elapsed_time);

    src->need_segment = FALSE;
  }

  if (src->cur_end_ts != GST_CLOCK_TIME_NONE) {
    segment->position = src->cur_end_ts;
    if (segment->stop != -1 && segment->position > segment->stop)
      segment->stop = segment->position;

    GST_LOG_OBJECT (src, "Segment position now %" GST_TIME_FORMAT,
        GST_TIME_ARGS (segment->position));
  }

  if (tags) {
    GstEvent *tag_event = gst_event_new_tag (tags);
    gst_pad_push_event (GST_BASE_SRC_PAD (src), tag_event);
    tags = NULL;
  }
  g_mutex_lock (src->dvd_lock);

  if (src->next_buf != NULL) {
    /* Now that we're in the new segment, we can enqueue any nav packet
     * correctly */
    if (src->next_is_nav_block) {
      rsn_dvdsrc_enqueue_nav_block (src, src->next_buf, src->next_nav_ts);
      src->next_is_nav_block = FALSE;
    }

    *outbuf = src->next_buf;
    src->next_buf = NULL;

    if (src->discont) {
      GST_LOG_OBJECT (src, "Marking discont buffer");
      GST_BUFFER_FLAG_SET (*outbuf, GST_BUFFER_FLAG_DISCONT);
      src->discont = FALSE;
    }
  }

  if (src->in_playing) {
    highlight_event = src->highlight_event;
    src->highlight_event = NULL;
  } else {
    highlight_event = NULL;
  }

  /* Schedule a clock callback for the any pending nav packet */
  rsn_dvdsrc_check_nav_blocks (src);

  g_mutex_unlock (src->dvd_lock);

  if (highlight_event) {
    GST_LOG_OBJECT (src, "Pushing highlight event with TS %" GST_TIME_FORMAT,
        GST_TIME_ARGS (GST_EVENT_TIMESTAMP (highlight_event)));
    gst_pad_push_event (GST_BASE_SRC_PAD (src), highlight_event);
  }

  if (angles_msg) {
    gst_element_post_message (GST_ELEMENT_CAST (src), angles_msg);
  }

  if (cmds_changed)
    rsn_dvdsrc_send_commands_changed (src);

  return ret;
}

static RsnNavResult
rsn_dvdsrc_perform_button_action (resinDvdSrc * src,
    GstNavigationCommand action)
{
  pci_t *pci;
  RsnNavResult result = RSN_NAV_RESULT_NONE;
  int button = 0;
  btni_t *btn_info;

  if (!src->have_pci)
    return RSN_NAV_RESULT_NONE;
  pci = &src->cur_pci;

  if (pci->hli.hl_gi.hli_ss == 0)
    return RSN_NAV_RESULT_NONE; /* No buttons at the moment */

  dvdnav_get_current_highlight (src->dvdnav, &button);

  if (button > pci->hli.hl_gi.btn_ns || button < 1)
    return RSN_NAV_RESULT_NONE; /* No valid button */

  btn_info = pci->hli.btnit + button - 1;

  switch (action) {
    case GST_NAVIGATION_COMMAND_ACTIVATE:
      if (dvdnav_button_activate (src->dvdnav, pci) == DVDNAV_STATUS_OK)
        result = RSN_NAV_RESULT_BRANCH_AND_HIGHLIGHT;
      break;
    case GST_NAVIGATION_COMMAND_LEFT:
      if (dvdnav_left_button_select (src->dvdnav, pci) == DVDNAV_STATUS_OK) {
        if (btn_info->left &&
            pci->hli.btnit[btn_info->left - 1].auto_action_mode)
          result = RSN_NAV_RESULT_BRANCH_AND_HIGHLIGHT;
        else
          result = RSN_NAV_RESULT_HIGHLIGHT;
      }
      break;
    case GST_NAVIGATION_COMMAND_RIGHT:
      if (dvdnav_right_button_select (src->dvdnav, pci) == DVDNAV_STATUS_OK) {
        if (btn_info->right &&
            pci->hli.btnit[btn_info->right - 1].auto_action_mode)
          result = RSN_NAV_RESULT_BRANCH_AND_HIGHLIGHT;
        else
          result = RSN_NAV_RESULT_HIGHLIGHT;
      }
      break;
    case GST_NAVIGATION_COMMAND_DOWN:
      if (dvdnav_lower_button_select (src->dvdnav, pci) == DVDNAV_STATUS_OK) {
        if (btn_info->down &&
            pci->hli.btnit[btn_info->down - 1].auto_action_mode)
          result = RSN_NAV_RESULT_BRANCH_AND_HIGHLIGHT;
        else
          result = RSN_NAV_RESULT_HIGHLIGHT;
      }
      break;
    case GST_NAVIGATION_COMMAND_UP:
      if (dvdnav_upper_button_select (src->dvdnav, pci) == DVDNAV_STATUS_OK) {
        if (btn_info->up && pci->hli.btnit[btn_info->up - 1].auto_action_mode)
          result = RSN_NAV_RESULT_BRANCH_AND_HIGHLIGHT;
        else
          result = RSN_NAV_RESULT_HIGHLIGHT;
      }
      break;
    default:
      break;
  }

  if (result == RSN_NAV_RESULT_HIGHLIGHT) {
    /* If we're *only* changing the highlight, wake up the still condition.
     * If we're branching, that will happen anyway */
    g_cond_broadcast (src->still_cond);
  }

  return result;
}

static RsnNavResult
rsn_dvdsrc_do_command (resinDvdSrc * src, GstNavigationCommand command)
{
  RsnNavResult result = RSN_NAV_RESULT_NONE;

  switch (command) {
    case GST_NAVIGATION_COMMAND_DVD_MENU:
      if (dvdnav_menu_call (src->dvdnav, DVD_MENU_Escape) == DVDNAV_STATUS_OK)
        result = RSN_NAV_RESULT_BRANCH;
      break;
    case GST_NAVIGATION_COMMAND_DVD_TITLE_MENU:
      if (dvdnav_menu_call (src->dvdnav, DVD_MENU_Title) == DVDNAV_STATUS_OK)
        result = RSN_NAV_RESULT_BRANCH;
      break;
    case GST_NAVIGATION_COMMAND_DVD_ROOT_MENU:
      if (dvdnav_menu_call (src->dvdnav, DVD_MENU_Root) == DVDNAV_STATUS_OK)
        result = RSN_NAV_RESULT_BRANCH;
      break;
    case GST_NAVIGATION_COMMAND_DVD_SUBPICTURE_MENU:
      if (dvdnav_menu_call (src->dvdnav, DVD_MENU_Subpicture) ==
          DVDNAV_STATUS_OK)
        result = RSN_NAV_RESULT_BRANCH;
      break;
    case GST_NAVIGATION_COMMAND_DVD_AUDIO_MENU:
      if (dvdnav_menu_call (src->dvdnav, DVD_MENU_Audio) == DVDNAV_STATUS_OK)
        result = RSN_NAV_RESULT_BRANCH;
      break;
    case GST_NAVIGATION_COMMAND_DVD_ANGLE_MENU:
      if (dvdnav_menu_call (src->dvdnav, DVD_MENU_Angle) == DVDNAV_STATUS_OK)
        result = RSN_NAV_RESULT_BRANCH;
      break;
    case GST_NAVIGATION_COMMAND_DVD_CHAPTER_MENU:
      if (dvdnav_menu_call (src->dvdnav, DVD_MENU_Part) == DVDNAV_STATUS_OK)
        result = RSN_NAV_RESULT_BRANCH;
      break;
    case GST_NAVIGATION_COMMAND_LEFT:
    case GST_NAVIGATION_COMMAND_RIGHT:
    case GST_NAVIGATION_COMMAND_UP:
    case GST_NAVIGATION_COMMAND_DOWN:
    case GST_NAVIGATION_COMMAND_ACTIVATE:
      return rsn_dvdsrc_perform_button_action (src, command);

    case GST_NAVIGATION_COMMAND_PREV_ANGLE:{
      gint32 cur, agls;
      gint new_angle = 0;
      if (dvdnav_get_angle_info (src->dvdnav, &cur, &agls) == DVDNAV_STATUS_OK) {
        if (cur > 0 &&
            dvdnav_angle_change (src->dvdnav, cur - 1) == DVDNAV_STATUS_OK) {
          new_angle = cur - 1;
        } else if (cur == 1 &&
            dvdnav_angle_change (src->dvdnav, agls) == DVDNAV_STATUS_OK) {
          new_angle = agls;
        }
        /* Angle switches are seamless and involve no branching */
        if (new_angle) {
          src->angles_changed = TRUE;
          GST_INFO_OBJECT (src, "Switched to angle %d", new_angle);
        }
      }
      break;
    }
    case GST_NAVIGATION_COMMAND_NEXT_ANGLE:{
      gint32 cur, agls;
      gint new_angle = 0;
      if (dvdnav_get_angle_info (src->dvdnav, &cur, &agls) == DVDNAV_STATUS_OK) {
        if (cur < agls
            && dvdnav_angle_change (src->dvdnav, cur + 1) == DVDNAV_STATUS_OK) {
          new_angle = cur + 1;
        } else if (cur == agls
            && dvdnav_angle_change (src->dvdnav, 1) == DVDNAV_STATUS_OK) {
          new_angle = 1;
        }
        /* Angle switches are seamless and involve no branching */
        if (new_angle) {
          src->angles_changed = TRUE;
          GST_INFO_OBJECT (src, "Switched to angle %d", new_angle);
        }
      }
      break;
    }
    default:
      break;
  }

  return result;
}

static gboolean
rsn_dvdsrc_handle_navigation_event (resinDvdSrc * src, GstEvent * event)
{
  gboolean have_lock = FALSE;
  GstEvent *hl_event = NULL;
  RsnNavResult nav_res = RSN_NAV_RESULT_NONE;
  GstNavigationEventType etype = gst_navigation_event_get_type (event);
  GstMessage *mouse_over_msg = NULL;
  GstMessage *angles_msg = NULL;

  switch (etype) {
    case GST_NAVIGATION_EVENT_KEY_PRESS:{
      const gchar *key;
      if (!gst_navigation_event_parse_key_event (event, &key))
        return FALSE;

      GST_DEBUG ("dvdnavsrc got a keypress: %s", key);

      g_mutex_lock (src->dvd_lock);
      have_lock = TRUE;
      if (!src->running)
        goto not_running;

      if (g_str_equal (key, "Return")) {
        nav_res = rsn_dvdsrc_do_command (src, GST_NAVIGATION_COMMAND_ACTIVATE);
      } else if (g_str_equal (key, "Left")) {
        nav_res = rsn_dvdsrc_do_command (src, GST_NAVIGATION_COMMAND_LEFT);
      } else if (g_str_equal (key, "Right")) {
        nav_res = rsn_dvdsrc_do_command (src, GST_NAVIGATION_COMMAND_RIGHT);
      } else if (g_str_equal (key, "Up")) {
        nav_res = rsn_dvdsrc_do_command (src, GST_NAVIGATION_COMMAND_UP);
      } else if (g_str_equal (key, "Down")) {
        nav_res = rsn_dvdsrc_do_command (src, GST_NAVIGATION_COMMAND_DOWN);
      } else if (g_str_equal (key, "m")) {
        nav_res = rsn_dvdsrc_do_command (src, GST_NAVIGATION_COMMAND_DVD_MENU);
      } else if (g_str_equal (key, "t")) {
        nav_res =
            rsn_dvdsrc_do_command (src, GST_NAVIGATION_COMMAND_DVD_TITLE_MENU);
      } else if (g_str_equal (key, "r")) {
        nav_res =
            rsn_dvdsrc_do_command (src, GST_NAVIGATION_COMMAND_DVD_ROOT_MENU);
      } else if (g_str_equal (key, "comma")) {
        gint title = 0;
        gint part = 0;

        if (dvdnav_current_title_info (src->dvdnav, &title, &part)) {
          if (title > 0 && part > 1) {
            dvdnav_prev_pg_search (src->dvdnav);
            nav_res = RSN_NAV_RESULT_BRANCH;
          }
        }
      } else if (g_str_equal (key, "period")) {
        dvdnav_next_pg_search (src->dvdnav);
        nav_res = RSN_NAV_RESULT_BRANCH;
      } else if (g_str_equal (key, "bracketleft")) {
        nav_res =
            rsn_dvdsrc_do_command (src, GST_NAVIGATION_COMMAND_PREV_ANGLE);
      } else if (g_str_equal (key, "bracketright")) {
        nav_res =
            rsn_dvdsrc_do_command (src, GST_NAVIGATION_COMMAND_NEXT_ANGLE);
      } else if (key && key[0] >= '1' && key[0] <= '8') {
        gint new_stream = key[0] - '1';
        GST_INFO_OBJECT (src, "Selecting audio stream %d", new_stream);
        rsn_dvdsrc_prepare_audio_stream_event (src, new_stream, new_stream);
      }
      break;
    }
    case GST_NAVIGATION_EVENT_MOUSE_MOVE:{
      gdouble x, y;

      if (!gst_navigation_event_parse_mouse_move_event (event, &x, &y))
        return FALSE;

      g_mutex_lock (src->dvd_lock);
      have_lock = TRUE;
      if (!src->running)
        goto not_running;

      if (src->have_pci &&
          dvdnav_mouse_select (src->dvdnav, &src->cur_pci, (int) x, (int) y) ==
          DVDNAV_STATUS_OK) {
        nav_res = RSN_NAV_RESULT_HIGHLIGHT;
        if (!src->was_mouse_over) {
          GST_DEBUG_OBJECT (src, "Mouse moved onto a button");
          mouse_over_msg =
              gst_navigation_message_new_mouse_over ((GstObject *) src, TRUE);
          src->was_mouse_over = TRUE;
        }
      } else if (src->was_mouse_over) {
        GST_DEBUG_OBJECT (src, "Mouse moved out of a button");
        mouse_over_msg =
            gst_navigation_message_new_mouse_over ((GstObject *) src, FALSE);
        src->was_mouse_over = FALSE;
      }
      break;
    }
    case GST_NAVIGATION_EVENT_MOUSE_BUTTON_RELEASE:{
      gdouble x, y;
      gint button;

      if (!gst_navigation_event_parse_mouse_button_event (event, &button, &x,
              &y))
        return FALSE;
      if (button != 1)
        return FALSE;

      GST_DEBUG_OBJECT (src, "Got click at %g, %g", x, y);

      g_mutex_lock (src->dvd_lock);
      have_lock = TRUE;
      if (!src->running)
        goto not_running;

      if (src->have_pci && dvdnav_mouse_activate (src->dvdnav, &src->cur_pci,
              (int) x, (int) y) == DVDNAV_STATUS_OK) {
        nav_res = RSN_NAV_RESULT_BRANCH_AND_HIGHLIGHT;
      }
      break;
    }
    case GST_NAVIGATION_EVENT_COMMAND:{
      GstNavigationCommand command;

      if (!gst_navigation_event_parse_command (event, &command))
        return FALSE;
      if (command == GST_NAVIGATION_COMMAND_INVALID)
        return FALSE;

      g_mutex_lock (src->dvd_lock);
      have_lock = TRUE;
      if (!src->running)
        goto not_running;

      GST_LOG_OBJECT (src, "handling navigation command %d", command);
      nav_res = rsn_dvdsrc_do_command (src, command);
      break;
    }
    default:
      return TRUE;
  }

  if (have_lock) {
    gboolean channel_hop = FALSE;
    gboolean cmds_changed;

    if (nav_res != RSN_NAV_RESULT_NONE) {
      if (nav_res == RSN_NAV_RESULT_BRANCH) {
        channel_hop = TRUE;
      } else if (nav_res == RSN_NAV_RESULT_BRANCH_AND_HIGHLIGHT) {
        src->active_highlight = TRUE;
        channel_hop = TRUE;
      }

      rsn_dvdsrc_update_highlight (src);
    }

    if (channel_hop) {
      GstEvent *seek;

      GST_DEBUG_OBJECT (src, "Processing flush and jump");
      g_mutex_lock (src->branch_lock);
      src->branching = TRUE;
      g_cond_broadcast (src->still_cond);
      g_mutex_unlock (src->branch_lock);

      hl_event = src->highlight_event;
      src->highlight_event = NULL;
      src->active_highlight = FALSE;

      g_mutex_unlock (src->dvd_lock);

      if (hl_event) {
        GST_DEBUG_OBJECT (src, "Sending highlight change event - button: %d",
            src->active_button);
        gst_pad_push_event (GST_BASE_SRC_PAD (src), hl_event);
      }

      /* Send ourselves a seek event to wake everything up and flush */
      seek = gst_event_new_seek (1.0, rsndvd_format, GST_SEEK_FLAG_FLUSH,
          GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_NONE, -1);
      src->flushing_seek = TRUE;
      gst_element_send_event (GST_ELEMENT (src), seek);

      g_mutex_lock (src->dvd_lock);

      rsn_dvdsrc_update_highlight (src);
    }

    hl_event = src->highlight_event;
    src->highlight_event = NULL;

    if (src->angles_changed) {
      gint cur, agls;
      if (dvdnav_get_angle_info (src->dvdnav, &cur, &agls) == DVDNAV_STATUS_OK) {

        angles_msg =
            gst_navigation_message_new_angles_changed (GST_OBJECT_CAST (src),
            cur, agls);
      }
      src->angles_changed = FALSE;

      src->need_tag_update = TRUE;
    }

    cmds_changed = src->commands_changed;
    src->commands_changed = FALSE;

    g_mutex_unlock (src->dvd_lock);

    if (hl_event) {
      GST_DEBUG_OBJECT (src, "Sending highlight change event - button: %d",
          src->active_button);
      gst_pad_push_event (GST_BASE_SRC_PAD (src), hl_event);
    }

    if (cmds_changed)
      rsn_dvdsrc_send_commands_changed (src);
  }

  if (mouse_over_msg) {
    gst_element_post_message (GST_ELEMENT_CAST (src), mouse_over_msg);
  }

  if (angles_msg) {
    gst_element_post_message (GST_ELEMENT_CAST (src), angles_msg);
  }

  return TRUE;
not_running:
  if (have_lock)
    g_mutex_unlock (src->dvd_lock);
  GST_DEBUG_OBJECT (src, "Element not started. Ignoring navigation event");
  return FALSE;
}

static void
rsn_dvdsrc_prepare_audio_stream_event (resinDvdSrc * src, guint8 logical_stream,
    guint8 phys_stream)
{
  GstStructure *s;
  GstEvent *e;

  if (phys_stream == src->cur_audio_phys_stream)
    return;
  src->cur_audio_phys_stream = phys_stream;

  GST_DEBUG_OBJECT (src, "Preparing audio change, phys %d", phys_stream);

  s = gst_structure_new ("application/x-gst-dvd",
      "event", G_TYPE_STRING, "dvd-set-audio-track",
      "logical-id", G_TYPE_INT, (gint) logical_stream,
      "physical-id", G_TYPE_INT, (gint) phys_stream, NULL);

  e = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s);

  if (src->audio_select_event)
    gst_event_unref (src->audio_select_event);
  src->audio_select_event = e;
}

static void
rsn_dvdsrc_prepare_spu_stream_event (resinDvdSrc * src, guint8 logical_stream,
    guint8 phys_stream, gboolean forced_only)
{
  GstStructure *s;
  GstEvent *e;

  if (phys_stream == src->cur_spu_phys_stream &&
      forced_only == src->cur_spu_forced_only) {
    return;
  }
  src->cur_spu_phys_stream = phys_stream;
  src->cur_spu_forced_only = forced_only;

  GST_DEBUG_OBJECT (src, "Preparing SPU change, log %d phys %d forced %d",
      logical_stream, phys_stream, forced_only);

  s = gst_structure_new ("application/x-gst-dvd",
      "event", G_TYPE_STRING, "dvd-set-subpicture-track",
      "logical-id", G_TYPE_INT, (gint) logical_stream,
      "physical-id", G_TYPE_INT, (gint) phys_stream,
      "forced-only", G_TYPE_BOOLEAN, forced_only, NULL);

  e = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s);

  if (src->spu_select_event)
    gst_event_unref (src->spu_select_event);
  src->spu_select_event = e;
}

static gboolean
rsn_dvdsrc_prepare_streamsinfo_event (resinDvdSrc * src)
{
  vtsi_mat_t *vts_attr;
  video_attr_t *v_attr;
  audio_attr_t *a_attrs;
  subp_attr_t *s_attrs;
  gint n_audio, n_subp;
  int8_t cur_audio;
  GstStructure *s;
  GstEvent *e;
  gint i;
  gchar lang_code[3] = { '\0', '\0', '\0' };
  gchar *t;
  gboolean is_widescreen;
  gboolean have_audio;
  gboolean have_subp;

  if (src->vts_n == 0 || src->vts_attrs == NULL) {
    /* VMGM info */
    vts_attr = NULL;
    v_attr = &src->vmgm_attr.vmgm_video_attr;
    a_attrs = &src->vmgm_attr.vmgm_audio_attr;
    n_audio = MIN (1, src->vmgm_attr.nr_of_vmgm_audio_streams);
    s_attrs = &src->vmgm_attr.vmgm_subp_attr;
    n_subp = MIN (1, src->vmgm_attr.nr_of_vmgm_subp_streams);
  } else if (src->in_menu) {
    /* VTSM attrs */
    vts_attr = get_vts_attr (src, src->vts_n);
    v_attr = &vts_attr->vtsm_video_attr;
    a_attrs = &vts_attr->vtsm_audio_attr;
    n_audio = MAX (1, vts_attr->nr_of_vtsm_audio_streams);
    s_attrs = &vts_attr->vtsm_subp_attr;
    n_subp = MAX (1, vts_attr->nr_of_vtsm_subp_streams);
  } else {
    /* VTS domain */
    vts_attr = get_vts_attr (src, src->vts_n);
    v_attr = &vts_attr->vts_video_attr;
    a_attrs = vts_attr->vts_audio_attr;
    n_audio = vts_attr->nr_of_vts_audio_streams;
    s_attrs = vts_attr->vts_subp_attr;
    n_subp = vts_attr->nr_of_vts_subp_streams;
  }

  if (src->vts_n > 0 && vts_attr == NULL)
    return FALSE;

  GST_DEBUG_OBJECT (src, "Preparing streamsinfo for %d audio and "
      "%d subpicture streams", n_audio, n_subp);

  /* build event */
  s = gst_structure_new ("application/x-gst-dvd",
      "event", G_TYPE_STRING, "dvd-lang-codes", NULL);
  e = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s);

  /* video */
  is_widescreen = (v_attr->display_aspect_ratio != 0);
  gst_structure_set (s, "video-pal-format", G_TYPE_BOOLEAN,
      (v_attr->video_format != 0), NULL);
  gst_structure_set (s, "video-widescreen", G_TYPE_BOOLEAN, is_widescreen,
      NULL);

  /* audio */
  cur_audio = dvdnav_get_active_audio_stream (src->dvdnav);

  have_audio = FALSE;
  for (i = 0; i < n_audio; i++) {
    const audio_attr_t *a = a_attrs + i;
    gint phys_id = dvdnav_get_audio_logical_stream (src->dvdnav, (guint) i);

    if (phys_id == -1) {
      GST_DEBUG_OBJECT (src, "No substream ID in map for audio %d. Skipping.",
          i);
      continue;
    }

    GST_DEBUG_OBJECT (src, "mapped logical audio %d to MPEG substream %d",
        i, phys_id);
    /* Force audio stream reselection in case format changed ... */
    if (i == cur_audio) {
      src->cur_audio_phys_stream = -1;
      rsn_dvdsrc_prepare_audio_stream_event (src, i, phys_id);
    }
#if 0
    /* Old test code: Only output A52 streams */
    if (a->audio_format != 0) {
      GST_DEBUG_OBJECT (src, "Ignoring non-A52 stream %d, format %d", i,
          (int) a->audio_format);
      continue;
    }
    if (a->audio_format == 0)
      have_audio = TRUE;
#else
    have_audio = TRUE;
#endif

    GST_DEBUG_OBJECT (src, "Audio stream %d is format %d, substream %d", i,
        (int) a->audio_format, phys_id);

    t = g_strdup_printf ("audio-%d-stream", i);
    gst_structure_set (s, t, G_TYPE_INT, phys_id, NULL);
    g_free (t);

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

    /* Check that the language code is flagged and at least somewhat valid
     * before putting it in the output structure */
    if (a->lang_type && a->lang_code > 0x100) {
      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);

      GST_DEBUG_OBJECT (src, "Audio stream %d is language %s", i, lang_code);
    } else
      GST_DEBUG_OBJECT (src, "Audio stream %d - no language", i);
  }

  if (have_audio == FALSE) {
    /* Always create at least one audio stream of the required type */
    gst_structure_set (s, "audio-0-format", G_TYPE_INT, (int) 0,
        "audio-0-stream", G_TYPE_INT, (int) 0, NULL);
  }

  /* subpictures */
  have_subp = FALSE;
  for (i = 0; i < n_subp; i++) {
    const subp_attr_t *u = s_attrs + i;
    gint phys_id = dvdnav_get_spu_logical_stream (src->dvdnav, (guint) i);

    if (phys_id == -1) {
      GST_DEBUG_OBJECT (src, "No substream ID in map for subpicture %d. "
          "Skipping", i);
      continue;
    }
    have_subp = TRUE;

    GST_DEBUG_OBJECT (src, "mapped logical subpicture %d to MPEG substream %d",
        i, phys_id);

    t = g_strdup_printf ("subpicture-%d-stream", i);
    gst_structure_set (s, t, G_TYPE_INT, (int) phys_id, 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);

    t = g_strdup_printf ("subpicture-%d-language", i);
    if (u->type && u->lang_code > 0x100) {
      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);
    } else {
      gst_structure_set (s, t, G_TYPE_STRING, "MENU", NULL);
    }
    g_free (t);

    GST_DEBUG_OBJECT (src, "Subpicture stream %d is language %s", i,
        lang_code[0] ? lang_code : "NONE");
  }
  if (!have_subp) {
    /* Always create at least one subpicture stream */
    gst_structure_set (s, "subpicture-0-format", G_TYPE_INT, (int) 0,
        "subpicture-0-language", G_TYPE_STRING, "MENU",
        "subpicture-0-stream", G_TYPE_INT, (int) 0, NULL);
  }

  if (src->streams_event)
    gst_event_unref (src->streams_event);
  src->streams_event = e;

  return TRUE;
}

static void
rsn_dvdsrc_prepare_clut_change_event (resinDvdSrc * src, const guint32 * clut)
{
  GstEvent *event;
  GstStructure *structure;
  gchar name[16];
  int i;

  if (memcmp (src->cur_clut, clut, sizeof (guint32) * 16) == 0)
    return;
  memcpy (src->cur_clut, clut, sizeof (guint32) * 16);

  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++) {
    sprintf (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. */
  event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, structure);

  GST_LOG_OBJECT (src, "preparing clut change event %" GST_PTR_FORMAT, event);

  if (src->clut_event)
    gst_event_unref (src->clut_event);
  src->clut_event = event;
}

/*
 * Check for a new highlighted area, and prepare an spu highlight event if
 * necessary.
 */
static void
rsn_dvdsrc_update_highlight (resinDvdSrc * src)
{
  int button = 0;
  pci_t *pci = &src->cur_pci;
  dvdnav_highlight_area_t area;
  int mode = src->active_highlight ? 1 : 0;
  GstEvent *event = NULL;
  GstStructure *s;

  if (src->have_pci) {
    if (dvdnav_get_current_highlight (src->dvdnav, &button) == DVDNAV_STATUS_OK) {
      GST_LOG_OBJECT (src, "current dvdnav button is %d, we have %d",
          button, src->active_button);
    }

    if (pci->hli.hl_gi.hli_ss == 0 || button < 0) {
      button = 0;
    } else if (button > pci->hli.hl_gi.btn_ns) {
      /* button is out of the range of possible buttons. */
      button = pci->hli.hl_gi.btn_ns;
      dvdnav_button_select (src->dvdnav, &src->cur_pci, button);
    }

    if (button > 0 && dvdnav_get_highlight_area (pci, button, mode,
            &area) != DVDNAV_STATUS_OK) {
      button = 0;
    }
  }

  if (button == 0) {
    /* No highlight available, or no button selected - clear the SPU */
    if (src->active_button != 0) {
      src->active_button = 0;

      s = gst_structure_new ("application/x-gst-dvd", "event",
          G_TYPE_STRING, "dvd-spu-reset-highlight", NULL);
      event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_OOB, s);
      if (src->highlight_event)
        gst_event_unref (src->highlight_event);
      src->highlight_event = event;
      if (src->cur_btn_mask != RSN_BTN_NONE) {
        src->cur_btn_mask = RSN_BTN_NONE;
        src->commands_changed = TRUE;
      }
    }
    return;
  }

  /* Check if we have a new button number, or a new highlight region. */
  if (button != src->active_button ||
      area.sx != src->area.sx || area.sy != src->area.sy ||
      area.ex != src->area.ex || area.ey != src->area.ey ||
      area.palette != src->area.palette) {
    btni_t *btn_info = pci->hli.btnit + button - 1;
    guint32 btn_mask;

    GST_DEBUG_OBJECT (src, "Setting highlight. Button %d @ %d,%d,%d,%d "
        "active %d palette 0x%x (from button %d @ %d,%d,%d,%d palette 0x%x)",
        button, area.sx, area.sy, area.ex, area.ey,
        mode, area.palette,
        src->active_button, src->area.sx, src->area.sy, src->area.ex,
        src->area.ey, src->area.palette);

    memcpy (&(src->area), &area, sizeof (dvdnav_highlight_area_t));

    s = gst_structure_new ("application/x-gst-dvd", "event",
        G_TYPE_STRING, "dvd-spu-highlight",
        "button", G_TYPE_INT, (gint) button,
        "palette", G_TYPE_INT, (gint) area.palette,
        "sx", G_TYPE_INT, (gint) area.sx,
        "sy", G_TYPE_INT, (gint) area.sy,
        "ex", G_TYPE_INT, (gint) area.ex,
        "ey", G_TYPE_INT, (gint) area.ey, NULL);

    event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_OOB, s);

    if (src->active_button < 1) {
      /* When setting the button for the first time, take the
         timestamp into account. */
      GST_EVENT_TIMESTAMP (event) = MPEGTIME_TO_GSTTIME (area.pts);
    }

    src->active_button = button;

    if (src->highlight_event)
      gst_event_unref (src->highlight_event);
    src->highlight_event = event;

    /* Calculate whether the available set of button motions is changed */
    btn_mask = 0;
    if (btn_info->left && btn_info->left != button)
      btn_mask |= RSN_BTN_LEFT;
    if (btn_info->right && btn_info->right != button)
      btn_mask |= RSN_BTN_RIGHT;
    if (btn_info->up && btn_info->up != button)
      btn_mask |= RSN_BTN_UP;
    if (btn_info->down && btn_info->down != button)
      btn_mask |= RSN_BTN_DOWN;

    if (btn_mask != src->cur_btn_mask) {
      src->cur_btn_mask = btn_mask;
      src->commands_changed = TRUE;
    }
  }
}

static void
rsn_dvdsrc_enqueue_nav_block (resinDvdSrc * src, GstBuffer * nav_buf,
    GstClockTime ts)
{
  RsnDvdPendingNav *pend_nav = g_new0 (RsnDvdPendingNav, 1);
  GstSegment *seg = &(GST_BASE_SRC (src)->segment);

  pend_nav->buffer = gst_buffer_ref (nav_buf);
  pend_nav->ts = ts;
  pend_nav->running_ts = gst_segment_to_running_time (seg, GST_FORMAT_TIME, ts);

  if (src->pending_nav_blocks == NULL) {
    src->pending_nav_blocks = src->pending_nav_blocks_end =
        g_slist_append (src->pending_nav_blocks_end, pend_nav);
  } else {
    src->pending_nav_blocks_end =
        g_slist_append (src->pending_nav_blocks_end, pend_nav);
    src->pending_nav_blocks_end = g_slist_next (src->pending_nav_blocks_end);
  }

  GST_LOG_OBJECT (src, "Enqueued nav with TS %" GST_TIME_FORMAT
      " with run ts %" GST_TIME_FORMAT ". %d packs pending",
      GST_TIME_ARGS (ts), GST_TIME_ARGS (pend_nav->running_ts),
      g_slist_length (src->pending_nav_blocks));
}

static void
rsn_dvdsrc_activate_nav_block (resinDvdSrc * src, GstBuffer * nav_buf)
{
  int32_t forced_button;

  {
    GstMapInfo mmap;
    gst_buffer_map (nav_buf, &mmap, GST_MAP_READ);

    navRead_PCI (&src->cur_pci, mmap.data + 0x2d);

    gst_buffer_unmap (nav_buf, &mmap);
  }

  src->have_pci = TRUE;

  forced_button = src->cur_pci.hli.hl_gi.fosl_btnn & 0x3f;
  if (forced_button != 0) {
    GST_DEBUG_OBJECT (src, "Selecting button %d based on nav packet command",
        forced_button);
    dvdnav_button_select (src->dvdnav, &src->cur_pci, forced_button);
  }
  /* highlight might change, let's check */
  rsn_dvdsrc_update_highlight (src);

  if (src->highlight_event && src->in_still_state) {
    GST_LOG_OBJECT (src, "Signalling still condition due to highlight change");
    g_cond_broadcast (src->still_cond);
  }
}

static void
rsn_dvdsrc_clear_nav_blocks (resinDvdSrc * src)
{
  GST_DEBUG_OBJECT (src, "Clearing %d pending navpacks",
      g_slist_length (src->pending_nav_blocks));

  while (src->pending_nav_blocks) {
    RsnDvdPendingNav *cur = (RsnDvdPendingNav *) src->pending_nav_blocks->data;

    gst_buffer_unref (cur->buffer);
    g_free (cur);

    src->pending_nav_blocks =
        g_slist_delete_link (src->pending_nav_blocks, src->pending_nav_blocks);
  }

  src->pending_nav_blocks_end = NULL;
}

static gboolean
rsn_dvdsrc_nav_clock_cb (GstClock * clock, GstClockTime time, GstClockID id,
    gpointer user_data)
{
  resinDvdSrc *src = (resinDvdSrc *) user_data;
  GstClockTime base_time = gst_element_get_base_time (GST_ELEMENT (src));

  GST_LOG_OBJECT (src, "NAV pack callback for TS %" GST_TIME_FORMAT " at ts %"
      GST_TIME_FORMAT, GST_TIME_ARGS (time),
      GST_TIME_ARGS (gst_clock_get_time (clock) - base_time));

  g_mutex_lock (src->dvd_lock);

  /* Destroy the clock id that caused this callback */
  if (src->nav_clock_id) {
    gst_clock_id_unref (src->nav_clock_id);
    src->nav_clock_id = NULL;
  }

  while (src->pending_nav_blocks) {
    RsnDvdPendingNav *cur = (RsnDvdPendingNav *) src->pending_nav_blocks->data;

    if (time < base_time + cur->running_ts)
      break;                    /* Next NAV is in the future */

    GST_DEBUG_OBJECT (src, "Activating nav pack with TS %" GST_TIME_FORMAT
        " at running TS %" GST_TIME_FORMAT, GST_TIME_ARGS (cur->ts),
        GST_TIME_ARGS (cur->running_ts));
    rsn_dvdsrc_activate_nav_block (src, cur->buffer);

    gst_buffer_unref (cur->buffer);
    g_free (cur);

    src->pending_nav_blocks =
        g_slist_delete_link (src->pending_nav_blocks, src->pending_nav_blocks);
  }

  if (src->pending_nav_blocks == NULL)
    src->pending_nav_blocks_end = NULL;
  else {
    /* Schedule a next packet, if any */
    RsnDvdPendingNav *next_nav =
        (RsnDvdPendingNav *) src->pending_nav_blocks->data;
    rsn_dvdsrc_schedule_nav_cb (src, next_nav);
  }

  g_mutex_unlock (src->dvd_lock);

  return TRUE;
}

/* Called with dvd_lock held. NOTE: Releases dvd_lock briefly */
static void
rsn_dvdsrc_schedule_nav_cb (resinDvdSrc * src, RsnDvdPendingNav * next_nav)
{
  GstClock *clock;
  GstClockTime base_ts;

  if (!src->in_playing) {
    GST_LOG_OBJECT (src, "Not scheduling NAV block - state != PLAYING");
    return;                     /* Not in playing state yet */
  }

  GST_OBJECT_LOCK (src);
  clock = GST_ELEMENT_CLOCK (src);
  base_ts = GST_ELEMENT (src)->base_time;

  if (clock == NULL) {
    GST_LOG_OBJECT (src, "Not scheduling NAV block - no clock yet");
    GST_OBJECT_UNLOCK (src);
    return;
  }
  gst_object_ref (clock);

  src->nav_clock_id = gst_clock_new_single_shot_id (clock,
      base_ts + next_nav->running_ts);

  GST_OBJECT_UNLOCK (src);

  GST_LOG_OBJECT (src, "Schedule nav pack for running TS %" GST_TIME_FORMAT,
      GST_TIME_ARGS (next_nav->running_ts));

  g_mutex_unlock (src->dvd_lock);
  gst_clock_id_wait_async (src->nav_clock_id, rsn_dvdsrc_nav_clock_cb, src,
      NULL);
  gst_object_unref (clock);
  g_mutex_lock (src->dvd_lock);
}

/* Called with dvd_lock held */
static void
rsn_dvdsrc_check_nav_blocks (resinDvdSrc * src)
{
  RsnDvdPendingNav *next_nav;

  /* Make sure a callback is scheduled for the first nav packet */
  if (src->nav_clock_id != NULL) {
    return;                     /* Something already scheduled */
  }
  if (src->pending_nav_blocks == NULL) {
    return;                     /* No nav blocks available yet */
  }
  if (!src->in_playing)
    return;                     /* Not in playing state yet */

  GST_LOG_OBJECT (src, "Installing NAV callback");
  next_nav = (RsnDvdPendingNav *) src->pending_nav_blocks->data;

  rsn_dvdsrc_schedule_nav_cb (src, next_nav);
}

static gboolean
rsn_dvdsrc_src_event (GstBaseSrc * basesrc, GstEvent * event)
{
  resinDvdSrc *src = RESINDVDSRC (basesrc);
  gboolean res;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_NAVIGATION:
      res = rsn_dvdsrc_handle_navigation_event (src, event);
      break;
    case GST_EVENT_SEEK:{
      GstSeekFlags flags;

      GST_LOG_OBJECT (src, "handling seek event");

      gst_event_parse_seek (event, NULL, NULL, &flags, NULL, NULL, NULL, NULL);
      src->flushing_seek = ! !(flags & GST_SEEK_FLAG_FLUSH);
      GST_DEBUG_OBJECT (src, "%s seek event",
          src->flushing_seek ? "flushing" : "non-flushing");

      res = GST_BASE_SRC_CLASS (parent_class)->event (basesrc, event);
      break;
    }
    default:
      GST_LOG_OBJECT (src, "handling %s event", GST_EVENT_TYPE_NAME (event));

      res = GST_BASE_SRC_CLASS (parent_class)->event (basesrc, event);
      break;
  }

  return res;
}

static void
rsn_dvdsrc_post_title_info (GstElement * element)
{
  resinDvdSrc *src = RESINDVDSRC (element);
  GstMessage *message;
  GstStructure *s;
  int32_t n, ntitles;
  int res;
  GValue array = { 0 };

  res = dvdnav_get_number_of_titles (src->dvdnav, &ntitles);
  if (res != DVDNAV_STATUS_OK) {
    GST_WARNING_OBJECT (src, "Failed to get number of titles: %d", res);
    return;
  }

  g_value_init (&array, GST_TYPE_ARRAY);

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

  for (n = 0; n < ntitles; ++n) {
    uint64_t *times, duration;
    uint32_t nchapters;
    GValue item = { 0 };

    g_value_init (&item, G_TYPE_UINT64);

    nchapters =
        dvdnav_describe_title_chapters (src->dvdnav, n, &times, &duration);
    if (nchapters == 0) {
      GST_WARNING_OBJECT (src, "Failed to get title %d info", n);
      g_value_set_uint64 (&item, GST_CLOCK_TIME_NONE);
    } else {
      g_value_set_uint64 (&item, gst_util_uint64_scale (duration, GST_SECOND,
              90000));
      free (times);
    }
    gst_value_array_append_value (&array, &item);
    g_value_unset (&item);
  }
  gst_structure_set_value (s, "title-durations", &array);
  g_value_unset (&array);

  message = gst_message_new_element (GST_OBJECT (src), s);
  gst_element_post_message (GST_ELEMENT_CAST (src), message);
}

static GstStateChangeReturn
rsn_dvdsrc_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn ret;
  resinDvdSrc *src = RESINDVDSRC (element);

  switch (transition) {
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      GST_DEBUG_OBJECT (element, "Switching to PAUSED");
      /* Unschedule any NAV packet callback */
      g_mutex_lock (src->dvd_lock);
      src->in_playing = FALSE;
      if (src->nav_clock_id) {
        gst_clock_id_unschedule (src->nav_clock_id);
        gst_clock_id_unref (src->nav_clock_id);
        src->nav_clock_id = NULL;
      }
      g_mutex_unlock (src->dvd_lock);
      break;
    default:
      break;
  }

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

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      GST_DEBUG_OBJECT (element, "Switching to PLAYING");
      /* Kick off the NAV packet callback if needed */
      g_mutex_lock (src->dvd_lock);
      src->in_playing = TRUE;
      rsn_dvdsrc_check_nav_blocks (src);
      g_mutex_unlock (src->dvd_lock);
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      rsn_dvdsrc_post_title_info (element);
      break;
    default:
      break;
  }

  return ret;
}

static gboolean
rsn_dvdsrc_src_query (GstBaseSrc * basesrc, GstQuery * query)
{
  resinDvdSrc *src = RESINDVDSRC (basesrc);
  gboolean res = FALSE;
  GstFormat format;
  gint64 val;

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_DURATION:
      gst_query_parse_duration (query, &format, NULL);
      g_mutex_lock (src->dvd_lock);
      if (!src->running) {
        g_mutex_unlock (src->dvd_lock);
        break;
      }

      if (format == GST_FORMAT_TIME) {
        if (src->pgc_duration != GST_CLOCK_TIME_NONE) {
          val = src->pgc_duration;

          GST_DEBUG_OBJECT (src, "duration : %" GST_TIME_FORMAT,
              GST_TIME_ARGS (val));
          gst_query_set_duration (query, format, val);
          res = TRUE;
        }
      } else if (format == title_format) {
        gint32 titles;

        if (dvdnav_get_number_of_titles (src->dvdnav,
                &titles) == DVDNAV_STATUS_OK) {
          val = titles;
          gst_query_set_duration (query, format, val);
          res = TRUE;
        }
      } else if (format == chapter_format) {
        gint32 title, chapters, x;

        if (dvdnav_current_title_info (src->dvdnav, &title,
                &x) == DVDNAV_STATUS_OK) {
          if (dvdnav_get_number_of_parts (src->dvdnav, title,
                  &chapters) == DVDNAV_STATUS_OK) {
            val = chapters;
            gst_query_set_duration (query, format, val);
            res = TRUE;
          }
        }
      }
      g_mutex_unlock (src->dvd_lock);
      break;
    case GST_QUERY_POSITION:
      gst_query_parse_position (query, &format, NULL);

      g_mutex_lock (src->dvd_lock);
      if (!src->running) {
        g_mutex_unlock (src->dvd_lock);
        break;
      }
      if (format == title_format) {
        gint32 title, chapter;

        if (dvdnav_current_title_info (src->dvdnav, &title,
                &chapter) == DVDNAV_STATUS_OK) {
          val = title;
          gst_query_set_position (query, format, val);
          res = TRUE;
        }
      } else if (format == chapter_format) {
        gint32 title, chapter = -1;

        if (dvdnav_current_title_info (src->dvdnav, &title,
                &chapter) == DVDNAV_STATUS_OK) {
          val = chapter;
          gst_query_set_position (query, format, val);
          res = TRUE;
        }
      }
      g_mutex_unlock (src->dvd_lock);
      break;
    case GST_QUERY_CUSTOM:
    {
      GstNavigationQueryType nq_type = gst_navigation_query_get_type (query);
      if (nq_type != GST_NAVIGATION_QUERY_INVALID)
        res = rsn_dvdsrc_handle_navigation_query (src, nq_type, query);
      else
        res = GST_BASE_SRC_CLASS (parent_class)->query (basesrc, query);
      break;
    }
    case GST_QUERY_SCHEDULING:
    {
      /* Make sure we operate in pull mode */
      gst_query_set_scheduling (query, GST_SCHEDULING_FLAG_SEQUENTIAL, 1, -1,
          0);
      gst_query_add_scheduling_mode (query, GST_PAD_MODE_PUSH);

      res = TRUE;
      break;
    }
    default:
      res = GST_BASE_SRC_CLASS (parent_class)->query (basesrc, query);
      break;
  }

  return res;
}

static gboolean
rsn_dvdsrc_is_seekable (GstBaseSrc * bsrc)
{
  return TRUE;
}

static gboolean
rsn_dvdsrc_prepare_seek (GstBaseSrc * bsrc, GstEvent * event,
    GstSegment * segment)
{
  GstSeekType cur_type, stop_type;
  gint64 cur, stop;
  GstSeekFlags flags;
  GstFormat seek_format;
  gdouble rate;
  gboolean update;
  gboolean ret;

  gst_event_parse_seek (event, &rate, &seek_format, &flags,
      &cur_type, &cur, &stop_type, &stop);

  /* Don't allow bytes seeks - angle, time, chapter, title only is the plan */
  if (seek_format == GST_FORMAT_BYTES)
    return FALSE;

  if (seek_format == rsndvd_format || seek_format == title_format ||
      seek_format == chapter_format) {
    /* Seeks in our internal formats are passed directly through to the do_seek
     * method. */
    gst_segment_init (segment, seek_format);
    gst_segment_do_seek (segment, rate, seek_format, flags, cur_type, cur,
        stop_type, stop, &update);

    return TRUE;
  }

  /* Let basesrc handle other formats */
  ret = GST_BASE_SRC_CLASS (parent_class)->prepare_seek_segment (bsrc,
      event, segment);

  return ret;
}

/* Find sector from time using time map if available */
static gint
rsn_dvdsrc_get_sector_from_time_tmap (resinDvdSrc * src, GstClockTime ts)
{
  vts_tmapt_t *vts_tmapt;
  vts_tmap_t *title_tmap;
  gint32 title, part, vts_ttn;
  guint32 entry, sector, logical_sector;
  gint cell_n;
  pgc_t *pgc;

  if (ts == 0)
    return 0;

  if (src->vts_file == NULL)
    return -1;

  if (dvdnav_current_title_info (src->dvdnav, &title, &part) !=
      DVDNAV_STATUS_OK)
    return -1;

  vts_tmapt = src->vts_file->vts_tmapt;
  if (vts_tmapt == NULL)
    return -1;

  /* To find the right tmap, we need the title number within this VTS (vts_ttn)
   * from the VMG tt_srpt table... */
  if (title < 1 || title > src->vmg_file->tt_srpt->nr_of_srpts)
    return -1;

  /* We must be in the correct VTS for any of this to succeed... */
  if (src->vts_n != src->vmg_file->tt_srpt->title[title - 1].title_set_nr)
    return -1;

  /* We must also be in the VTS domain to use the tmap table */
  if (src->vts_n == 0 || src->in_menu)
    return -1;

  vts_ttn = src->vmg_file->tt_srpt->title[title - 1].vts_ttn;

  GST_DEBUG_OBJECT (src, "Seek to time %" GST_TIME_FORMAT
      " in VTS %d title %d (vts_ttn %d of %d)",
      GST_TIME_ARGS (ts), src->vts_n, title, vts_ttn, vts_tmapt->nr_of_tmaps);

  if (vts_ttn < 1 || vts_ttn > vts_tmapt->nr_of_tmaps)
    return -1;

  pgc = get_current_pgc (src);
  if (pgc == NULL)
    return -1;

  /* Get the time map */
  title_tmap = vts_tmapt->tmap + vts_ttn - 1;
  if (title_tmap->tmu == 0)
    return -1;

  entry = ts / (title_tmap->tmu * GST_SECOND);
  if (entry == 0)
    return 0;

  if (entry < 1 || entry > title_tmap->nr_of_entries)
    return -1;

  sector = title_tmap->map_ent[entry - 1] & 0x7fffffff;

  GST_LOG_OBJECT (src, "Got sector %u for time seek (entry %d of %d)",
      sector, entry, title_tmap->nr_of_entries);

  /* Sector is now an absolute sector within the current VTS, but
   * dvdnav_sector_search expects a logical sector within the current PGC...
   * which means iterating over the cells of the current PGC until we find
   * the cell that contains the time and sector we want, accumulating
   * the logical sector offsets until we find it
   */
  logical_sector = 0;
  for (cell_n = 0; cell_n < pgc->nr_of_cells; cell_n++) {
    cell_playback_t *cell = pgc->cell_playback + cell_n;

    /* This matches how libdvdnav calculates the logical sector
     * in dvdnav_sector_search(): */

    if (sector >= cell->first_sector && sector <= cell->last_sector) {
      logical_sector += sector - cell->first_sector;
      break;
    }

    if (cell->block_type == BLOCK_TYPE_ANGLE_BLOCK &&
        cell->block_mode != BLOCK_MODE_FIRST_CELL)
      continue;

    logical_sector += (cell->last_sector - cell->first_sector + 1);
  }

  GST_DEBUG_OBJECT (src, "Mapped sector %u onto PGC relative sector %u",
      sector, logical_sector);

  return logical_sector;
}

/* call with DVD lock held */
static gboolean
rsn_dvdsrc_seek_to_time (resinDvdSrc * src, GstClockTime ts)
{
  gint sector;
  dvdnav_status_t res;

  GST_DEBUG_OBJECT (src, "Time seek requested to ts %" GST_TIME_FORMAT,
      GST_TIME_ARGS (ts));

  sector = rsn_dvdsrc_get_sector_from_time_tmap (src, ts);
  if (sector < 0)
    return FALSE;

  src->discont = TRUE;
  res = dvdnav_sector_search (src->dvdnav, sector, SEEK_SET);

  if (res != DVDNAV_STATUS_OK)
    return FALSE;

  return TRUE;
}

static gboolean
rsn_dvdsrc_do_seek (GstBaseSrc * bsrc, GstSegment * segment)
{
  resinDvdSrc *src = RESINDVDSRC (bsrc);
  gboolean ret = FALSE;

  if (segment->format == rsndvd_format || src->first_seek) {
    /* The internal format has alread served its purpose of waking
     * everything up and flushing, we just need to step to the next
     * data block (below) so we know our new position */
    ret = TRUE;
    /* HACK to make initial seek work: */
    src->first_seek = FALSE;
  } else {
    /* Handle other formats: Time, title, chapter, angle */
    if (segment->format == GST_FORMAT_TIME) {
      g_mutex_lock (src->dvd_lock);
      src->discont = TRUE;
      ret = rsn_dvdsrc_seek_to_time (src, segment->start);
      g_mutex_unlock (src->dvd_lock);
    } else if (segment->format == title_format) {
      gint titles;

      g_mutex_lock (src->dvd_lock);
      if (src->running &&
          dvdnav_get_number_of_titles (src->dvdnav,
              &titles) == DVDNAV_STATUS_OK) {
        if (segment->start > 0 && segment->start <= titles) {
          dvdnav_title_play (src->dvdnav, segment->start);
          ret = TRUE;
          src->discont = TRUE;
        }
      }
      g_mutex_unlock (src->dvd_lock);
    } else if (segment->format == chapter_format) {
      g_mutex_lock (src->dvd_lock);
      if (src->running) {
        gint32 title, chapters, x;
        if (dvdnav_current_title_info (src->dvdnav, &title, &x) ==
            DVDNAV_STATUS_OK) {
          if (segment->start + 1 == x) {
            /* if already on the first part, don't try to get before it */
            if (segment->start == 0) {
              dvdnav_part_play (src->dvdnav, title, 1);
            } else {
              dvdnav_prev_pg_search (src->dvdnav);
            }
            ret = TRUE;
            src->discont = TRUE;
          } else if (segment->start == x + 1) {
            dvdnav_next_pg_search (src->dvdnav);
            ret = TRUE;
            src->discont = TRUE;
          } else if (dvdnav_get_number_of_parts (src->dvdnav, title,
                  &chapters) == DVDNAV_STATUS_OK) {
            if (segment->start > 0 && segment->start <= chapters) {
              dvdnav_part_play (src->dvdnav, title, segment->start);
              ret = TRUE;
              src->discont = TRUE;
            }
          }
        }
      }
      g_mutex_unlock (src->dvd_lock);
    }
  }

  if (ret) {
    /* Force a highlight update */
    src->active_button = -1;

    if (src->flushing_seek) {
      GstMessage *mouse_over_msg = NULL;
      g_mutex_lock (src->dvd_lock);
      src->flushing_seek = FALSE;

      gst_buffer_replace (&src->next_buf, NULL);
      src->cur_start_ts = GST_CLOCK_TIME_NONE;
      src->cur_end_ts = GST_CLOCK_TIME_NONE;
      src->cur_vobu_base_ts = GST_CLOCK_TIME_NONE;
      src->have_pci = FALSE;
      if (src->nav_clock_id) {
        gst_clock_id_unschedule (src->nav_clock_id);
        gst_clock_id_unref (src->nav_clock_id);
        src->nav_clock_id = NULL;
      }
      rsn_dvdsrc_clear_nav_blocks (src);
      if (src->was_mouse_over) {
        mouse_over_msg =
            gst_navigation_message_new_mouse_over ((GstObject *) src, FALSE);
        src->was_mouse_over = FALSE;
      }
      g_mutex_unlock (src->dvd_lock);

      if (mouse_over_msg)
        gst_element_post_message (GST_ELEMENT_CAST (src), mouse_over_msg);
    }

    GST_LOG_OBJECT (src, "Entering prepare_next_block after seek."
        " Flushing = %d", src->flushing_seek);
    while (src->cur_start_ts == GST_CLOCK_TIME_NONE) {
      if (rsn_dvdsrc_prepare_next_block (src, FALSE) != GST_FLOW_OK)
        goto fail;
      if (src->cur_start_ts == GST_CLOCK_TIME_NONE)
        gst_buffer_replace (&src->next_buf, NULL);
    }
    GST_LOG_OBJECT (src, "prepare_next_block after seek done");

    segment->format = GST_FORMAT_TIME;
    /* The first TS output: */
    segment->position = segment->start = src->cur_start_ts;
    GST_LOG_OBJECT (src, "Segment position now %" GST_TIME_FORMAT,
        GST_TIME_ARGS (segment->position));

    /* time field = position is the 'logical' stream time here: */
    segment->time = 0;
    if (src->cur_position != GST_CLOCK_TIME_NONE)
      segment->time += src->cur_position;
    if (src->cur_vobu_base_ts != GST_CLOCK_TIME_NONE)
      segment->time += src->cur_vobu_base_ts;

    segment->stop = -1;
    segment->duration = -1;

    GST_DEBUG_OBJECT (src, "seek completed. New start TS %" GST_TIME_FORMAT
        " pos %" GST_TIME_FORMAT " (offset %" GST_TIME_FORMAT ")",
        GST_TIME_ARGS (segment->start), GST_TIME_ARGS (segment->time),
        GST_TIME_ARGS ((GstClockTimeDiff) (segment->start - segment->time)));

    src->need_segment = FALSE;
  }

  return ret;
fail:
  GST_DEBUG_OBJECT (src, "Seek in format %d failed", segment->format);
  return FALSE;
}
