mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-22 23:28:16 +00:00
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:
parent
f8ccb04412
commit
4252e5c174
4 changed files with 77 additions and 7 deletions
21
ChangeLog
21
ChangeLog
|
@ -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>
|
||||
|
||||
* ext/mad/gstid3tag.c: (gst_id3_tag_get_type):
|
||||
|
|
|
@ -282,6 +282,9 @@ gst_dvd_demux_init (GstDVDDemux * dvd_demux, GstDVDDemuxClass * klass)
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -301,6 +304,11 @@ gst_dvd_demux_process_event (GstMPEGParse * mpeg_parse, GstEvent * event)
|
|||
gboolean ret = TRUE;
|
||||
|
||||
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_OOB:
|
||||
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_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) {
|
||||
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_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")) {
|
||||
gint num_substreams = 0, num_audstreams = 0, n;
|
||||
gchar *t;
|
||||
|
@ -910,6 +930,19 @@ gst_dvd_demux_send_subbuffer (GstMPEGDemux * mpeg_demux,
|
|||
GstPad *outpad;
|
||||
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
|
||||
in case, we keep a reference to the buffer during the execution
|
||||
of this function. */
|
||||
|
|
|
@ -104,6 +104,15 @@ struct _GstDVDDemux {
|
|||
GstMPEGStream *subpicture_stream[GST_DVD_DEMUX_NUM_SUBPICTURE_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;
|
||||
};
|
||||
|
||||
|
|
|
@ -293,8 +293,15 @@ gst_mpeg_parse_adjust_ts (GstMPEGParse * mpeg_parse, GstClockTime ts)
|
|||
} else {
|
||||
/* Adjust the timestamp in such a way that all segments appear to
|
||||
be in a single continuous sequence starting at time 0. */
|
||||
return ts + mpeg_parse->current_segment.accum -
|
||||
mpeg_parse->current_segment.start;
|
||||
if (ts + mpeg_parse->current_segment.accum >=
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue