resindvd: Fiddle with segment handling for DVD.

Clarify some of the terms used, and make sure to extend the
stop time when the position moves past the end of the current
segment (as for still frames, for example).

Also, make sure to reset the position value of the segment the
demuxer outputs when collecting a seamless segment.
This commit is contained in:
Jan Schmidt 2012-09-30 03:49:17 +10:00
parent f1f7171aa9
commit 3c1a1dfec5
2 changed files with 46 additions and 19 deletions

View file

@ -846,7 +846,7 @@ gst_flups_demux_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
const GstSegment *segment;
gint64 start, stop, time;
gint64 base, dur;
gint64 base, dur, position;
GstClockTimeDiff adjust;
gst_event_parse_segment (event, &segment);
@ -872,22 +872,23 @@ gst_flups_demux_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
"demux: received new segment start %" G_GINT64_FORMAT " stop %"
G_GINT64_FORMAT " time %" G_GINT64_FORMAT
" base %" G_GINT64_FORMAT, start, stop, time, base);
adjust = base - start + SCR_MUNGE;
base = 0;
start = base + SCR_MUNGE;
#if 0
g_print ("demux: received new segment start %" G_GINT64_FORMAT " stop %"
G_GINT64_FORMAT " time %" G_GINT64_FORMAT
" base %" G_GINT64_FORMAT "\n", start, stop, time, base);
#endif
position = base - start;
adjust = position + SCR_MUNGE;
if (adjust >= 0)
demux->scr_adjust = GSTTIME_TO_MPEGTIME (adjust);
else
demux->scr_adjust = -GSTTIME_TO_MPEGTIME (-adjust);
if (stop != -1) {
start = SCR_MUNGE;
base = 0;
if (stop != -1)
stop = start + dur;
if (demux->src_segment.position != -1
&& demux->src_segment.position > stop)
stop = demux->src_segment.position;
}
demux->src_segment.rate = segment->rate;
demux->src_segment.applied_rate = segment->applied_rate;
@ -896,6 +897,7 @@ gst_flups_demux_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
demux->src_segment.stop = stop;
demux->src_segment.time = time;
demux->src_segment.base = base;
demux->src_segment.position = position;
GST_DEBUG_OBJECT (demux,
"sending new segment: rate %g format %d, start: %"
@ -905,6 +907,15 @@ gst_flups_demux_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
segment->rate, segment->format, start, stop, time, base,
demux->scr_adjust,
GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (demux->scr_adjust)));
#if 0
g_print ("sending new segment: rate %g format %d, start: %"
G_GINT64_FORMAT ", stop: %" G_GINT64_FORMAT ", time: %"
G_GINT64_FORMAT ", base: %" G_GINT64_FORMAT
", scr_adjust: %" G_GINT64_FORMAT "(%" GST_TIME_FORMAT ")\n",
segment->rate, segment->format, start, stop, time, base,
demux->scr_adjust,
GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (demux->scr_adjust)));
#endif
if (demux->in_still && stop != -1) {
/* Generate gap buffers, due to closing segment from a still-frame */

View file

@ -631,6 +631,8 @@ rsn_dvdsrc_do_still (resinDvdSrc * src, int duration)
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);
@ -748,8 +750,14 @@ rsn_dvdsrc_do_still (resinDvdSrc * src, int duration)
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)
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);
@ -1365,27 +1373,33 @@ rsn_dvdsrc_create (GstBaseSrc * bsrc, guint64 offset,
if (src->need_segment) {
/* Seamless segment update */
GstClockTime position = 0;
GstClockTime elapsed_time = 0;
if (src->cur_position != GST_CLOCK_TIME_NONE)
position += src->cur_position;
elapsed_time += src->cur_position;
if (src->cur_vobu_base_ts != GST_CLOCK_TIME_NONE)
position += src->cur_vobu_base_ts;
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 " position %" 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 (position));
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, position);
src->cur_start_ts, -1, elapsed_time);
src->need_segment = FALSE;
}
if (src->cur_end_ts != GST_CLOCK_TIME_NONE)
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);
@ -2907,6 +2921,8 @@ rsn_dvdsrc_do_seek (GstBaseSrc * bsrc, GstSegment * segment)
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;