gst/mpegstream/gstdvddemux.c (gst_dvd_demux_handle_dvd_event): Use the new "audio-shutdown" and "audio-restart" DVD e...

Original commit message from CVS:
2005-12-31  Martin Soto  <martinsoto@users.sourceforge.net>

* gst/mpegstream/gstdvddemux.c (gst_dvd_demux_handle_dvd_event):
Use the new "audio-shutdown" and "audio-restart" DVD events
instead of the "spu-still-frame" event to shutdown and restart
the audio pipeline.

* gst/mpegstream/gstmpegparse.c (gst_mpeg_parse_adjust_ts):
Check for cases where the segment-based adjustment calculation
would produce negative values (which result in an overflow) and
return GST_CLOCK_TIME_NONE instead.

* gst/mpegstream/gstdvddemux.h:
* gst/mpegstream/gstdvddemux.c (gst_dvd_demux_init)
(gst_dvd_demux_process_event, gst_dvd_demux_send_subbuffer):
Add a mechanism to discard audio buffers with timestamps outside
the currently set segment. This was causing (sometimes serious)
synchronization problems after seeking in DVDs with LPCM audio,
since VOBUs usually contain audio material that lies outside the
timestamp range specified by the header.
This commit is contained in:
Martin Soto 2005-12-30 23:51:46 +00:00
parent f8ccb04412
commit 4252e5c174
4 changed files with 77 additions and 7 deletions

View file

@ -1,3 +1,24 @@
2005-12-31 Martin Soto <martinsoto@users.sourceforge.net>
* gst/mpegstream/gstdvddemux.c (gst_dvd_demux_handle_dvd_event):
Use the new "audio-shutdown" and "audio-restart" DVD events
instead of the "spu-still-frame" event to shutdown and restart
the audio pipeline.
* gst/mpegstream/gstmpegparse.c (gst_mpeg_parse_adjust_ts):
Check for cases where the segment-based adjustment calculation
would produce negative values (which result in an overflow) and
return GST_CLOCK_TIME_NONE instead.
* gst/mpegstream/gstdvddemux.h:
* gst/mpegstream/gstdvddemux.c (gst_dvd_demux_init)
(gst_dvd_demux_process_event, gst_dvd_demux_send_subbuffer):
Add a mechanism to discard audio buffers with timestamps outside
the currently set segment. This was causing (sometimes serious)
synchronization problems after seeking in DVDs with LPCM audio,
since VOBUs usually contain audio material that lies outside the
timestamp range specified by the header.
2005-12-30 Jan Schmidt <thaytan@mad.scientist.com> 2005-12-30 Jan Schmidt <thaytan@mad.scientist.com>
* ext/mad/gstid3tag.c: (gst_id3_tag_get_type): * ext/mad/gstid3tag.c: (gst_id3_tag_get_type):

View file

@ -282,6 +282,9 @@ gst_dvd_demux_init (GstDVDDemux * dvd_demux, GstDVDDemuxClass * klass)
dvd_demux->subpicture_stream[i] = NULL; dvd_demux->subpicture_stream[i] = NULL;
} }
/* Directly after starting we operate as if we had just flushed. */
dvd_demux->flush_filter = TRUE;
dvd_demux->langcodes = NULL; dvd_demux->langcodes = NULL;
} }
@ -301,6 +304,11 @@ gst_dvd_demux_process_event (GstMPEGParse * mpeg_parse, GstEvent * event)
gboolean ret = TRUE; gboolean ret = TRUE;
switch (GST_EVENT_TYPE (event)) { switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_FLUSH_STOP:
dvd_demux->flush_filter = TRUE;
ret = GST_MPEG_PARSE_CLASS (parent_class)->process_event (mpeg_parse,
event);
break;
case GST_EVENT_CUSTOM_DOWNSTREAM: case GST_EVENT_CUSTOM_DOWNSTREAM:
case GST_EVENT_CUSTOM_DOWNSTREAM_OOB: case GST_EVENT_CUSTOM_DOWNSTREAM_OOB:
if (gst_structure_has_name (gst_event_get_structure (event), if (gst_structure_has_name (gst_event_get_structure (event),
@ -350,6 +358,23 @@ gst_dvd_demux_handle_dvd_event (GstDVDDemux * dvd_demux, GstEvent * event)
} }
gst_dvd_demux_set_cur_audio (dvd_demux, stream_nr); gst_dvd_demux_set_cur_audio (dvd_demux, stream_nr);
gst_event_unref (event); gst_event_unref (event);
} else if (strcmp (event_type, "dvd-audio-shutdown") == 0) {
/* Send an EOS down the audio path to effectively shut it down and
allow for preroll in the absence of audio material. */
gst_event_unref (event);
return gst_pad_push_event (dvd_demux->cur_audio, gst_event_new_eos ());
} else if (strcmp (event_type, "dvd-audio-restart") == 0) {
/* Restart the audio pipeline after an EOS by flushing it. */
gst_event_unref (event);
if (!gst_pad_push_event (dvd_demux->cur_audio,
gst_event_new_flush_start ())) {
return FALSE;
}
if (!gst_pad_push_event (dvd_demux->cur_audio, gst_event_new_flush_stop ())) {
return FALSE;
}
dvd_demux->flush_filter = TRUE;
return TRUE;
} else if (strcmp (event_type, "dvd-spu-stream-change") == 0) { } else if (strcmp (event_type, "dvd-spu-stream-change") == 0) {
gint stream_nr; gint stream_nr;
@ -361,11 +386,6 @@ gst_dvd_demux_handle_dvd_event (GstDVDDemux * dvd_demux, GstEvent * event)
} }
gst_dvd_demux_set_cur_subpicture (dvd_demux, stream_nr); gst_dvd_demux_set_cur_subpicture (dvd_demux, stream_nr);
gst_event_unref (event); gst_event_unref (event);
} else if (strcmp (event_type, "dvd-spu-still-frame") == 0) {
/* Send an EOS down the audio path, to allow for preroll in the
absence of audio material. */
gst_event_unref (event);
return gst_pad_push_event (dvd_demux->cur_audio, gst_event_new_eos ());
} else if (!strcmp (event_type, "dvd-lang-codes")) { } else if (!strcmp (event_type, "dvd-lang-codes")) {
gint num_substreams = 0, num_audstreams = 0, n; gint num_substreams = 0, num_audstreams = 0, n;
gchar *t; gchar *t;
@ -910,6 +930,19 @@ gst_dvd_demux_send_subbuffer (GstMPEGDemux * mpeg_demux,
GstPad *outpad; GstPad *outpad;
gint cur_nr; gint cur_nr;
if (dvd_demux->flush_filter &&
GST_MPEG_DEMUX_STREAM_KIND (outstream->type) ==
GST_MPEG_DEMUX_STREAM_AUDIO) {
/* We are in flush_filter mode and have an audio buffer. */
if (GST_CLOCK_TIME_IS_VALID (timestamp)) {
/* This is the first valid audio buffer after the flush. */
dvd_demux->flush_filter = FALSE;
} else {
/* Discard the buffer, */
return GST_FLOW_OK;
}
}
/* You never know what happens to a buffer when you send it. Just /* You never know what happens to a buffer when you send it. Just
in case, we keep a reference to the buffer during the execution in case, we keep a reference to the buffer during the execution
of this function. */ of this function. */

View file

@ -104,6 +104,15 @@ struct _GstDVDDemux {
GstMPEGStream *subpicture_stream[GST_DVD_DEMUX_NUM_SUBPICTURE_STREAMS]; GstMPEGStream *subpicture_stream[GST_DVD_DEMUX_NUM_SUBPICTURE_STREAMS];
/* Subpicture output streams. */ /* Subpicture output streams. */
gboolean flush_filter; /* If TRUE, the demuxer refrains from
sending any audio packets until it
sees one with a valid
timestamp. This is used to avoid
sending audio packets that lie
outside (actually before) the
current segment, which may happen
after a seek operation. */
GstEvent *langcodes; GstEvent *langcodes;
}; };

View file

@ -293,8 +293,15 @@ gst_mpeg_parse_adjust_ts (GstMPEGParse * mpeg_parse, GstClockTime ts)
} else { } else {
/* Adjust the timestamp in such a way that all segments appear to /* Adjust the timestamp in such a way that all segments appear to
be in a single continuous sequence starting at time 0. */ be in a single continuous sequence starting at time 0. */
return ts + mpeg_parse->current_segment.accum - if (ts + mpeg_parse->current_segment.accum >=
mpeg_parse->current_segment.start; mpeg_parse->current_segment.start) {
return ts + mpeg_parse->current_segment.accum -
mpeg_parse->current_segment.start;
} else {
/* The adjustment would lead to a timestamp outside the current
segment. Return an invalid timestamp instead. */
return GST_CLOCK_TIME_NONE;
}
} }
} }