From efb22b550c297f70e1d5fc320d3e0985f3c89613 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Fri, 27 Jun 2025 10:51:05 +0200 Subject: [PATCH] mpegtsdemux: Add property to disable skew corrections This is for cases where: * We *do* want to refer to the PCR stream to figure out global positioning, gap detection, wrapover correction. * But we do not want to apply any skew correction to the output This is useful for cases where: * the input stream has already been clock-corrected (for example with mpegtslivesrc) * or where the output doesn't require synchronization against a clock (ex: for storage) Part-of: --- .../docs/plugins/gst_plugins_cache.json | 12 +++++++++ .../gst/mpegtsdemux/mpegtsbase.c | 27 +++++++++++++++++-- .../gst/mpegtsdemux/mpegtspacketizer.c | 3 +++ .../gst/mpegtsdemux/mpegtspacketizer.h | 2 ++ 4 files changed, 42 insertions(+), 2 deletions(-) diff --git a/subprojects/gst-plugins-bad/docs/plugins/gst_plugins_cache.json b/subprojects/gst-plugins-bad/docs/plugins/gst_plugins_cache.json index c9eeb6d46b..7434f4bf47 100644 --- a/subprojects/gst-plugins-bad/docs/plugins/gst_plugins_cache.json +++ b/subprojects/gst-plugins-bad/docs/plugins/gst_plugins_cache.json @@ -225993,6 +225993,18 @@ "readable": true, "type": "gboolean", "writable": true + }, + "skew-corrections": { + "blurb": "Apply skew corrections", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "true", + "mutable": "null", + "readable": true, + "type": "gboolean", + "writable": true } } } diff --git a/subprojects/gst-plugins-bad/gst/mpegtsdemux/mpegtsbase.c b/subprojects/gst-plugins-bad/gst/mpegtsdemux/mpegtsbase.c index e69fb37152..3a54e10be2 100644 --- a/subprojects/gst-plugins-bad/gst/mpegtsdemux/mpegtsbase.c +++ b/subprojects/gst-plugins-bad/gst/mpegtsdemux/mpegtsbase.c @@ -60,13 +60,15 @@ static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", ); #define DEFAULT_IGNORE_PCR FALSE +#define DEFAULT_SKEW_CORRECTIONS TRUE enum { PROP_0, PROP_PARSE_PRIVATE_SECTIONS, PROP_IGNORE_PCR, - /* FILL ME */ + PROP_SKEW_CORRECTIONS + /* FILL ME */ }; static void mpegts_base_dispose (GObject * object); @@ -149,7 +151,7 @@ mpegts_base_class_init (MpegTSBaseClass * klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /** - * GstMpegtsBase:ignore-pcr: + * MpegTSBase:ignore-pcr: * * Ignore PCR (Program Clock Reference) data from MPEG-TS PSI. * This can help with playback of some broken files. @@ -161,6 +163,20 @@ mpegts_base_class_init (MpegTSBaseClass * klass) "Ignore PCR stream for timing", DEFAULT_IGNORE_PCR, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * MpegTSBase:skew-corrections: + * + * With push TIME inputs, apply continuous skew corrections to the output. The + * default is enabled. You can disable it if downstream doesn't require live + * synchronization. + * + * Since: 1.28 + */ + g_object_class_install_property (gobject_class, PROP_SKEW_CORRECTIONS, + g_param_spec_boolean ("skew-corrections", "Apply skew corrections", + "Apply skew corrections", DEFAULT_SKEW_CORRECTIONS, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + klass->sink_query = GST_DEBUG_FUNCPTR (mpegts_base_default_sink_query); klass->handle_psi = NULL; @@ -180,6 +196,9 @@ mpegts_base_set_property (GObject * object, guint prop_id, case PROP_IGNORE_PCR: base->ignore_pcr = g_value_get_boolean (value); break; + case PROP_SKEW_CORRECTIONS: + base->packetizer->skew_correction = g_value_get_boolean (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } @@ -198,6 +217,9 @@ mpegts_base_get_property (GObject * object, guint prop_id, case PROP_IGNORE_PCR: g_value_set_boolean (value, base->ignore_pcr); break; + case PROP_SKEW_CORRECTIONS: + g_value_set_boolean (value, base->packetizer->skew_correction); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } @@ -269,6 +291,7 @@ mpegts_base_init (MpegTSBase * base) base->disposed = FALSE; base->packetizer = mpegts_packetizer_new (); + base->packetizer->skew_correction = DEFAULT_SKEW_CORRECTIONS; base->programs = g_ptr_array_new_full (16, (GDestroyNotify) mpegts_base_free_program); diff --git a/subprojects/gst-plugins-bad/gst/mpegtsdemux/mpegtspacketizer.c b/subprojects/gst-plugins-bad/gst/mpegtsdemux/mpegtspacketizer.c index 78a4982bb5..aaf878bd0d 100644 --- a/subprojects/gst-plugins-bad/gst/mpegtsdemux/mpegtspacketizer.c +++ b/subprojects/gst-plugins-bad/gst/mpegtsdemux/mpegtspacketizer.c @@ -1471,6 +1471,9 @@ calculate_skew (MpegTSPacketizer2 * packetizer, /* keep track of the last extended pcrtime */ pcr->last_pcrtime = gstpcrtime; + if (!packetizer->skew_correction) + goto no_skew; + /* we don't have an arrival timestamp so we can't do skew detection. we * should still apply a timestamp based on RTP timestamp and base_time */ if (!GST_CLOCK_TIME_IS_VALID (time) diff --git a/subprojects/gst-plugins-bad/gst/mpegtsdemux/mpegtspacketizer.h b/subprojects/gst-plugins-bad/gst/mpegtsdemux/mpegtspacketizer.h index 3a3038b1df..d607d171fb 100644 --- a/subprojects/gst-plugins-bad/gst/mpegtsdemux/mpegtspacketizer.h +++ b/subprojects/gst-plugins-bad/gst/mpegtsdemux/mpegtspacketizer.h @@ -259,6 +259,8 @@ struct _MpegTSPacketizer2 { /* clock skew calculation */ gboolean calculate_skew; + /* skew_correction: apply skew correction to values */ + gboolean skew_correction; /* offset/bitrate calculator */ gboolean calculate_offset;