gst/mpegstream/: Timestamps in mpeg stream are 32-bit numbers. Therefore, with a clock_freq of 90kHz this timestamp o...

Original commit message from CVS:
Patch by: Michal Benes <michal dot benes at xeris dot cz>
* gst/mpegstream/gstmpegdemux.c: (gst_mpeg_demux_init),
(gst_mpeg_demux_parse_packet), (gst_mpeg_demux_parse_pes),
(gst_mpeg_demux_send_subbuffer), (gst_mpeg_demux_reset):
* gst/mpegstream/gstmpegdemux.h:
* gst/mpegstream/gstmpegparse.c: (gst_mpeg_parse_parse_packhead):
Timestamps in mpeg stream are 32-bit numbers. Therefore, with a
clock_freq of 90kHz this timestamp overflows every ~13 hours. This
situation really happens when grabbing DVB streams. Current
mpegdemuxer can not handle this situation correctly and it
restarts counting gstreamer timestamps from zero.
Fixes #326598.
This commit is contained in:
Michal Benes 2006-03-23 18:17:34 +00:00 committed by Wim Taymans
parent c2a98834b6
commit 39531423c5
5 changed files with 50 additions and 1 deletions

View file

@ -1,3 +1,19 @@
2006-03-23 Wim Taymans <wim@fluendo.com>
Patch by: Michal Benes <michal dot benes at xeris dot cz>
* gst/mpegstream/gstmpegdemux.c: (gst_mpeg_demux_init),
(gst_mpeg_demux_parse_packet), (gst_mpeg_demux_parse_pes),
(gst_mpeg_demux_send_subbuffer), (gst_mpeg_demux_reset):
* gst/mpegstream/gstmpegdemux.h:
* gst/mpegstream/gstmpegparse.c: (gst_mpeg_parse_parse_packhead):
Timestamps in mpeg stream are 32-bit numbers. Therefore, with a
clock_freq of 90kHz this timestamp overflows every ~13 hours. This
situation really happens when grabbing DVB streams. Current
mpegdemuxer can not handle this situation correctly and it
restarts counting gstreamer timestamps from zero.
Fixes #326598.
2006-03-15 Michael Smith <msmith@fluendo.com>
* ext/a52dec/gsta52dec.c: (gst_a52dec_sink_event),

2
common

@ -1 +1 @@
Subproject commit 9200457d08a57f0d7eaeb56915804fa8faf14418
Subproject commit 252846b570144570a0aee25b5adefbfac3f5d4eb

View file

@ -225,6 +225,8 @@ gst_mpeg_demux_init (GstMPEGDemux * mpeg_demux, GstMPEGDemuxClass * klass)
mpeg_demux->max_gap = GST_CLOCK_TIME_NONE;
mpeg_demux->max_gap_tolerance = GST_CLOCK_TIME_NONE;
mpeg_demux->last_pts = -1;
}
static GstFlowReturn
@ -682,6 +684,15 @@ done:
headerlen, datalen);
if (pts != -1) {
/* Check for pts overflow */
if (mpeg_demux->last_pts != -1) {
gint32 diff = pts - mpeg_demux->last_pts;
if (diff > -4 * CLOCK_FREQ && diff < 4 * CLOCK_FREQ)
pts = mpeg_demux->last_pts + diff;
}
mpeg_demux->last_pts = pts;
timestamp = PARSE_CLASS (mpeg_parse)->adjust_ts (mpeg_parse,
MPEGTIME_TO_GSTTIME (pts));
@ -780,6 +791,15 @@ gst_mpeg_demux_parse_pes (GstMPEGParse * mpeg_parse, GstBuffer * buffer)
pts |= ((guint64) * buf++) << 7;
pts |= ((guint64) (*buf++ & 0xFE)) >> 1;
/* Check for pts overflow */
if (mpeg_demux->last_pts != -1) {
gint32 diff = pts - mpeg_demux->last_pts;
if (diff > -4 * CLOCK_FREQ && diff < 4 * CLOCK_FREQ)
pts = mpeg_demux->last_pts + diff;
}
mpeg_demux->last_pts = pts;
timestamp = PARSE_CLASS (mpeg_parse)->adjust_ts (mpeg_parse,
MPEGTIME_TO_GSTTIME (pts));
@ -904,6 +924,7 @@ gst_mpeg_demux_send_subbuffer (GstMPEGDemux * mpeg_demux,
GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET (buffer) + offset;
GST_BUFFER_CAPS (outbuf) = gst_caps_ref (outstream->caps);
ret = gst_pad_push (outstream->pad, outbuf);
if (GST_CLOCK_TIME_IS_VALID (mpeg_demux->max_gap) &&
@ -1197,6 +1218,7 @@ gst_mpeg_demux_reset (GstMPEGDemux * mpeg_demux)
mpeg_demux->total_size_bound = 0LL;
mpeg_demux->index = NULL;
mpeg_demux->last_pts = -1;
/*
* Don't adjust things that are only for subclass use

View file

@ -123,6 +123,7 @@ struct _GstMPEGDemux {
gboolean packet_rate_restriction;
gint64 total_size_bound;
gint64 last_pts;
GstIndex *index;
/* stream output */

View file

@ -526,6 +526,16 @@ gst_mpeg_parse_parse_packhead (GstMPEGParse * mpeg_parse, GstBuffer * buffer)
}
new_rate *= MP_MUX_RATE_MULT;
/* Deal with SCR overflow */
if (mpeg_parse->current_scr != MP_INVALID_SCR) {
guint32 diff;
diff = scr - mpeg_parse->current_scr;
if (diff < 4 * CLOCK_FREQ)
scr = mpeg_parse->current_scr + diff;
}
prev_scr = mpeg_parse->current_scr;
mpeg_parse->current_scr = scr;