mpegtspacketizer: Handle rollover in offset calculations
This commit is contained in:
parent
d798cb7be3
commit
416b10b991
@ -31,6 +31,10 @@
|
|||||||
/* Skew calculation pameters */
|
/* Skew calculation pameters */
|
||||||
#define MAX_TIME (2 * GST_SECOND)
|
#define MAX_TIME (2 * GST_SECOND)
|
||||||
|
|
||||||
|
/* maximal PCR time */
|
||||||
|
#define PCR_MAX_VALUE (((((guint64)1)<<33) * 300) + 298)
|
||||||
|
#define PTS_DTS_MAX_VALUE (((guint64)1) << 33)
|
||||||
|
|
||||||
#include "mpegtspacketizer.h"
|
#include "mpegtspacketizer.h"
|
||||||
#include "gstmpegdesc.h"
|
#include "gstmpegdesc.h"
|
||||||
|
|
||||||
@ -89,8 +93,10 @@ struct _MpegTSPacketizerPrivate
|
|||||||
/* FIXME : Replace this later on with a balanced tree or sequence */
|
/* FIXME : Replace this later on with a balanced tree or sequence */
|
||||||
guint64 first_offset;
|
guint64 first_offset;
|
||||||
guint64 first_pcr;
|
guint64 first_pcr;
|
||||||
|
GstClockTime first_pcr_ts;
|
||||||
guint64 last_offset;
|
guint64 last_offset;
|
||||||
guint64 last_pcr;
|
guint64 last_pcr;
|
||||||
|
GstClockTime last_pcr_ts;
|
||||||
|
|
||||||
/* Reference offset */
|
/* Reference offset */
|
||||||
guint64 refoffset;
|
guint64 refoffset;
|
||||||
@ -206,8 +212,10 @@ mpegts_packetizer_init (MpegTSPacketizer2 * packetizer)
|
|||||||
|
|
||||||
packetizer->priv->first_offset = -1;
|
packetizer->priv->first_offset = -1;
|
||||||
packetizer->priv->first_pcr = -1;
|
packetizer->priv->first_pcr = -1;
|
||||||
|
packetizer->priv->first_pcr_ts = GST_CLOCK_TIME_NONE;
|
||||||
packetizer->priv->last_offset = -1;
|
packetizer->priv->last_offset = -1;
|
||||||
packetizer->priv->last_pcr = -1;
|
packetizer->priv->last_pcr = -1;
|
||||||
|
packetizer->priv->last_pcr_ts = GST_CLOCK_TIME_NONE;
|
||||||
packetizer->priv->nb_seen_offsets = 0;
|
packetizer->priv->nb_seen_offsets = 0;
|
||||||
packetizer->priv->refoffset = -1;
|
packetizer->priv->refoffset = -1;
|
||||||
}
|
}
|
||||||
@ -3140,6 +3148,7 @@ record_pcr (MpegTSPacketizer2 * packetizer, guint64 pcr, guint64 offset)
|
|||||||
GST_DEBUG ("Recording first value. PCR:%" G_GUINT64_FORMAT " offset:%"
|
GST_DEBUG ("Recording first value. PCR:%" G_GUINT64_FORMAT " offset:%"
|
||||||
G_GUINT64_FORMAT, pcr, offset);
|
G_GUINT64_FORMAT, pcr, offset);
|
||||||
priv->first_pcr = pcr;
|
priv->first_pcr = pcr;
|
||||||
|
priv->first_pcr_ts = PCRTIME_TO_GSTTIME (pcr);
|
||||||
priv->first_offset = offset;
|
priv->first_offset = offset;
|
||||||
priv->nb_seen_offsets++;
|
priv->nb_seen_offsets++;
|
||||||
} else
|
} else
|
||||||
@ -3147,7 +3156,12 @@ record_pcr (MpegTSPacketizer2 * packetizer, guint64 pcr, guint64 offset)
|
|||||||
if (priv->last_pcr == -1 || priv->last_offset < offset) {
|
if (priv->last_pcr == -1 || priv->last_offset < offset) {
|
||||||
GST_DEBUG ("Recording last value. PCR:%" G_GUINT64_FORMAT " offset:%"
|
GST_DEBUG ("Recording last value. PCR:%" G_GUINT64_FORMAT " offset:%"
|
||||||
G_GUINT64_FORMAT, pcr, offset);
|
G_GUINT64_FORMAT, pcr, offset);
|
||||||
|
if (G_UNLIKELY (priv->first_pcr != -1 && pcr < priv->first_pcr)) {
|
||||||
|
GST_DEBUG ("rollover detected");
|
||||||
|
pcr += PCR_MAX_VALUE;
|
||||||
|
}
|
||||||
priv->last_pcr = pcr;
|
priv->last_pcr = pcr;
|
||||||
|
priv->last_pcr_ts = PCRTIME_TO_GSTTIME (pcr);
|
||||||
priv->last_offset = offset;
|
priv->last_offset = offset;
|
||||||
priv->nb_seen_offsets++;
|
priv->nb_seen_offsets++;
|
||||||
}
|
}
|
||||||
@ -3185,23 +3199,30 @@ mpegts_packetizer_offset_to_ts (MpegTSPacketizer2 * packetizer, guint64 offset)
|
|||||||
}
|
}
|
||||||
|
|
||||||
GstClockTime
|
GstClockTime
|
||||||
mpegts_packetizer_pts_to_ts (MpegTSPacketizer2 * packetizer, guint64 pts)
|
mpegts_packetizer_pts_to_ts (MpegTSPacketizer2 * packetizer, GstClockTime pts)
|
||||||
{
|
{
|
||||||
|
GstClockTime res = GST_CLOCK_TIME_NONE;
|
||||||
|
|
||||||
/* Use clock skew if present */
|
/* Use clock skew if present */
|
||||||
if (packetizer->calculate_skew
|
if (packetizer->calculate_skew
|
||||||
&& GST_CLOCK_TIME_IS_VALID (packetizer->base_time)) {
|
&& GST_CLOCK_TIME_IS_VALID (packetizer->base_time)) {
|
||||||
GST_DEBUG ("pts %" G_GUINT64_FORMAT " base_pcrtime:%" G_GUINT64_FORMAT
|
GST_DEBUG ("pts %" G_GUINT64_FORMAT " base_pcrtime:%" G_GUINT64_FORMAT
|
||||||
" base_time:%" GST_TIME_FORMAT, pts, packetizer->base_pcrtime,
|
" base_time:%" GST_TIME_FORMAT, pts, packetizer->base_pcrtime,
|
||||||
GST_TIME_ARGS (packetizer->base_time));
|
GST_TIME_ARGS (packetizer->base_time));
|
||||||
return pts - packetizer->base_pcrtime + packetizer->base_time +
|
res = pts - packetizer->base_pcrtime + packetizer->base_time +
|
||||||
packetizer->skew;
|
packetizer->skew;
|
||||||
|
} else
|
||||||
|
/* If not, use pcr observations */
|
||||||
|
if (packetizer->calculate_offset && packetizer->priv->first_pcr != -1) {
|
||||||
|
/* Rollover */
|
||||||
|
if (G_UNLIKELY (pts < packetizer->priv->first_pcr_ts))
|
||||||
|
pts += MPEGTIME_TO_GSTTIME (PTS_DTS_MAX_VALUE);
|
||||||
|
res = pts - packetizer->priv->first_pcr_ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If not, use pcr observations */
|
GST_DEBUG ("Returning timestamp %" GST_TIME_FORMAT " for pts %"
|
||||||
if (packetizer->calculate_offset && packetizer->priv->first_pcr != -1)
|
GST_TIME_FORMAT, GST_TIME_ARGS (res), GST_TIME_ARGS (pts));
|
||||||
return pts - PCRTIME_TO_GSTTIME (packetizer->priv->first_pcr);
|
return res;
|
||||||
|
|
||||||
return GST_CLOCK_TIME_NONE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
guint64
|
guint64
|
||||||
|
@ -206,7 +206,7 @@ mpegts_packetizer_ts_to_offset (MpegTSPacketizer2 * packetizer,
|
|||||||
GstClockTime ts);
|
GstClockTime ts);
|
||||||
GstClockTime
|
GstClockTime
|
||||||
mpegts_packetizer_pts_to_ts (MpegTSPacketizer2 * packetizer,
|
mpegts_packetizer_pts_to_ts (MpegTSPacketizer2 * packetizer,
|
||||||
guint64 pcr);
|
GstClockTime pts);
|
||||||
void
|
void
|
||||||
mpegts_packetizer_set_reference_offset (MpegTSPacketizer2 * packetizer,
|
mpegts_packetizer_set_reference_offset (MpegTSPacketizer2 * packetizer,
|
||||||
guint64 refoffset);
|
guint64 refoffset);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user