mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-24 17:44:14 +00:00
ext/resindvd/: Add support for time based seeking.
Original commit message from CVS: * ext/resindvd/resindvdbin.c: * ext/resindvd/resindvdsrc.c: * ext/resindvd/resindvdsrc.h: * ext/resindvd/rsnaudiomunge.c: Add support for time based seeking. Make setting dvd:// reset to the default device. Make the 'audiomunge' element send any new segment start before the 'gap filler' buffer it generates, and any segment closes after. Fixes: #566957
This commit is contained in:
parent
acd634eafa
commit
672051c5eb
5 changed files with 121 additions and 11 deletions
13
ChangeLog
13
ChangeLog
|
@ -1,3 +1,16 @@
|
|||
2009-01-08 Jan Schmidt <jan.schmidt@sun.com>
|
||||
|
||||
* ext/resindvd/resindvdbin.c:
|
||||
* ext/resindvd/resindvdsrc.c:
|
||||
* ext/resindvd/resindvdsrc.h:
|
||||
* ext/resindvd/rsnaudiomunge.c:
|
||||
Add support for time based seeking.
|
||||
Make setting dvd:// reset to the default device.
|
||||
Make the 'audiomunge' element send any new segment start before
|
||||
the 'gap filler' buffer it generates, and any segment closes
|
||||
after.
|
||||
Fixes: #566957
|
||||
|
||||
2009-01-08 Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
||||
|
||||
* ext/ladspa/gstladspa.c: (plugin_init):
|
||||
|
|
|
@ -230,7 +230,10 @@ rsn_dvdbin_uri_set_uri (GstURIHandler * handler, const gchar * uri)
|
|||
*/
|
||||
if (g_str_has_prefix (uri, "dvd://")) {
|
||||
g_free (dvdbin->device);
|
||||
dvdbin->device = g_strdup (uri + 6);
|
||||
if (strlen (uri) > 6)
|
||||
dvdbin->device = g_strdup (uri + 6);
|
||||
else
|
||||
dvdbin->device = g_strdup (DEFAULT_DEVICE);
|
||||
}
|
||||
#if 0
|
||||
/*
|
||||
|
|
|
@ -337,6 +337,14 @@ rsn_dvdsrc_start (RsnBaseSrc * bsrc)
|
|||
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;
|
||||
}
|
||||
|
||||
|
||||
src->first_seek = TRUE;
|
||||
src->running = TRUE;
|
||||
src->branching = FALSE;
|
||||
src->discont = TRUE;
|
||||
|
@ -767,10 +775,16 @@ rsn_dvdsrc_step (resinDvdSrc * src, gboolean have_dvd_lock)
|
|||
case DVDNAV_VTS_CHANGE:{
|
||||
dvdnav_vts_change_event_t *event = (dvdnav_vts_change_event_t *) data;
|
||||
|
||||
if (dvdnav_is_domain_vmgm (src->dvdnav))
|
||||
if (dvdnav_is_domain_vmgm (src->dvdnav)) {
|
||||
src->vts_n = 0;
|
||||
else
|
||||
} 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_vtsm (src->dvdnav);
|
||||
|
||||
|
@ -1873,23 +1887,90 @@ rsn_dvdsrc_prepare_seek (RsnBaseSrc * bsrc, GstEvent * event,
|
|||
event, segment);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
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;
|
||||
|
||||
/* 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;
|
||||
|
||||
vts_tmapt = src->vts_file->vts_tmapt;
|
||||
if (vts_tmapt == NULL)
|
||||
return -1;
|
||||
|
||||
vts_ttn = src->vmg_file->tt_srpt->title[title - 1].vts_ttn;
|
||||
|
||||
if (vts_ttn < 1 || vts_ttn > vts_tmapt->nr_of_tmaps)
|
||||
return -1;
|
||||
|
||||
title_tmap = vts_tmapt->tmap + vts_ttn - 1;
|
||||
entry = ts / (title_tmap->tmu * GST_SECOND);
|
||||
|
||||
if (entry < title_tmap->nr_of_entries)
|
||||
return title_tmap->map_ent[entry] & 0x7fffffff;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 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 (RsnBaseSrc * bsrc, GstSegment * segment)
|
||||
{
|
||||
resinDvdSrc *src = RESINDVDSRC (bsrc);
|
||||
gboolean ret = FALSE;
|
||||
|
||||
if (segment->format == rsndvd_format) {
|
||||
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;
|
||||
src->first_seek = FALSE;
|
||||
} else {
|
||||
/* FIXME: Handle other formats: Time, title, chapter, angle */
|
||||
/* HACK to make initial seek work: */
|
||||
if (segment->format == GST_FORMAT_TIME) {
|
||||
ret = TRUE;
|
||||
src->discont = TRUE;
|
||||
g_mutex_lock (src->dvd_lock);
|
||||
ret = rsn_dvdsrc_seek_to_time (src, segment->start);
|
||||
g_mutex_unlock (src->dvd_lock);
|
||||
} else if (segment->format == title_format) {
|
||||
gint titles;
|
||||
|
||||
|
|
|
@ -85,6 +85,7 @@ struct _resinDvdSrc
|
|||
|
||||
gboolean running;
|
||||
gboolean discont;
|
||||
gboolean first_seek;
|
||||
gboolean flushing_seek;
|
||||
gboolean need_segment;
|
||||
gboolean active_highlight;
|
||||
|
|
|
@ -311,6 +311,15 @@ rsn_audiomunge_sink_event (GstPad * pad, GstEvent * event)
|
|||
* Otherwise, send the buffer before the newsegment, so that it appears
|
||||
* in the closing segment.
|
||||
*/
|
||||
if (!update) {
|
||||
GST_DEBUG_OBJECT (munge, "Sending newsegment: start %" GST_TIME_FORMAT
|
||||
" stop %" GST_TIME_FORMAT " accum now %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (start), GST_TIME_ARGS (stop),
|
||||
GST_TIME_ARGS (segment->accum));
|
||||
|
||||
ret = gst_pad_push_event (munge->srcpad, event);
|
||||
}
|
||||
|
||||
if (segment->accum >= AUDIO_FILL_THRESHOLD || munge->in_still) {
|
||||
g_print ("*********** Sending audio fill: accum = %" GST_TIME_FORMAT
|
||||
" still-state=%d\n", GST_TIME_ARGS (segment->accum),
|
||||
|
@ -326,12 +335,15 @@ rsn_audiomunge_sink_event (GstPad * pad, GstEvent * event)
|
|||
GST_TIME_ARGS (segment->accum));
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (munge, "Sending newsegment: start %" GST_TIME_FORMAT
|
||||
" stop %" GST_TIME_FORMAT " accum now %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (start), GST_TIME_ARGS (stop),
|
||||
GST_TIME_ARGS (segment->accum));
|
||||
if (update) {
|
||||
GST_DEBUG_OBJECT (munge, "Sending newsegment: start %" GST_TIME_FORMAT
|
||||
" stop %" GST_TIME_FORMAT " accum now %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (start), GST_TIME_ARGS (stop),
|
||||
GST_TIME_ARGS (segment->accum));
|
||||
|
||||
ret = gst_pad_push_event (munge->srcpad, event);
|
||||
}
|
||||
|
||||
ret = gst_pad_push_event (munge->srcpad, event);
|
||||
break;
|
||||
}
|
||||
case GST_EVENT_CUSTOM_DOWNSTREAM:
|
||||
|
|
Loading…
Reference in a new issue