resindvd: Send a title tag when we change chapter/menu/angle

Allow apps like Totem to display a nicer title that reflects the current
position on the disc.
This commit is contained in:
Jan Schmidt 2009-05-06 21:19:13 +01:00
parent f7fad4a88b
commit a5fbb123ca
2 changed files with 76 additions and 6 deletions

View file

@ -374,6 +374,8 @@ rsn_dvdsrc_start (RsnBaseSrc * bsrc)
}
}
dvdnav_get_title_string (src->dvdnav, &src->disc_name);
src->first_seek = TRUE;
src->running = TRUE;
src->branching = FALSE;
@ -388,6 +390,8 @@ rsn_dvdsrc_start (RsnBaseSrc * bsrc)
src->vts_n = 0;
src->in_menu = FALSE;
src->title_n = -1;
src->part_n = -1;
src->active_button = -1;
@ -519,6 +523,8 @@ rsn_dvdsrc_stop (RsnBaseSrc * bsrc)
src->highlight_event = NULL;
}
src->disc_name = NULL;
if (src->dvdnav) {
if (dvdnav_close (src->dvdnav) != DVDNAV_STATUS_OK) {
GST_ELEMENT_ERROR (src, RESOURCE, CLOSE, (NULL),
@ -725,6 +731,71 @@ get_current_pgc (resinDvdSrc * src)
return pgc;
}
static void
update_title_info (resinDvdSrc * src)
{
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) {
src->angles_changed = TRUE;
src->n_angles = n_angles;
}
if (dvdnav_current_title_info (src->dvdnav, &title_n,
&part_n) == DVDNAV_STATUS_OK) {
if (title_n != src->title_n || part_n != src->part_n || src->angles_changed) {
gchar *title_str = NULL;
src->title_n = title_n;
src->part_n = part_n;
if (title_n == 0) {
static const char *dvd_menu_map[] = {
NULL, NULL, "Title", "Root",
"Subpicture", "Audio", "Angle", "Part"
};
/* In a menu */
if (part_n >= 0 && part_n < G_N_ELEMENTS (dvd_menu_map)
&& dvd_menu_map[part_n]) {
title_str = g_strdup_printf ("DVD %s Menu", dvd_menu_map[part_n]);
} else {
title_str = g_strdup ("DVD Menu");
}
} else {
/* 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_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_TITLE,
title_str, NULL);
gst_element_found_tags (GST_ELEMENT_CAST (src), tags);
}
}
}
}
static GstFlowReturn
rsn_dvdsrc_step (resinDvdSrc * src, gboolean have_dvd_lock)
{
@ -862,7 +933,6 @@ rsn_dvdsrc_step (resinDvdSrc * src, gboolean have_dvd_lock)
break;
case DVDNAV_CELL_CHANGE:{
dvdnav_cell_change_event_t *event = (dvdnav_cell_change_event_t *) data;
gint n_angles, cur;
src->pgc_duration = MPEGTIME_TO_GSTTIME (event->pgc_length);
/* event->cell_start has the wrong time - it doesn't handle
@ -878,11 +948,7 @@ rsn_dvdsrc_step (resinDvdSrc * src, gboolean have_dvd_lock)
rsn_dvdsrc_prepare_streamsinfo_event (src);
if (dvdnav_get_angle_info (src->dvdnav, &cur,
&n_angles) == DVDNAV_STATUS_OK && src->n_angles != n_angles) {
src->angles_changed = TRUE;
src->n_angles = n_angles;
}
update_title_info (src);
break;
}

View file

@ -58,6 +58,8 @@ struct _resinDvdSrc
gchar *device;
dvdnav_t *dvdnav;
const char *disc_name;
/* dvd_reader instance is used to load and cache VTS/VMG ifo info */
dvd_reader_t *dvdread;
@ -72,6 +74,8 @@ struct _resinDvdSrc
/* Current playback location: VTS 0 = VMG, plus in_menu or not */
gint vts_n;
gboolean in_menu;
gint title_n; /* Title num */
gint part_n; /* Part num */
gboolean running;
gboolean discont;