tsdemux: Make latency configurable

Allows for "low latency" mpeg-ts mode which is not standard, but somewhat common.
For this to work the sender has to put timestamps at a higher frequency than the spec requires.
This commit is contained in:
Olivier Crête 2019-08-23 17:55:00 -04:00
parent 403cffeace
commit 963dda3482
2 changed files with 23 additions and 4 deletions

View file

@ -72,8 +72,8 @@
#define GST_FLOW_REWINDING GST_FLOW_CUSTOM_ERROR #define GST_FLOW_REWINDING GST_FLOW_CUSTOM_ERROR
/* latency in nsecs */ /* latency in msecs */
#define TS_LATENCY (700 * GST_MSECOND) #define DEFAULT_LATENCY (700)
/* Limit PES packet collection to a maximum of 32MB /* Limit PES packet collection to a maximum of 32MB
* which is more than large enough to support an H264 frame at * which is more than large enough to support an H264 frame at
@ -289,6 +289,7 @@ enum
PROP_0, PROP_0,
PROP_PROGRAM_NUMBER, PROP_PROGRAM_NUMBER,
PROP_EMIT_STATS, PROP_EMIT_STATS,
PROP_LATENCY,
/* FILL ME */ /* FILL ME */
}; };
@ -381,6 +382,12 @@ gst_ts_demux_class_init (GstTSDemuxClass * klass)
"Emit messages for every pcr/opcr/pts/dts", FALSE, "Emit messages for every pcr/opcr/pts/dts", FALSE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_LATENCY,
g_param_spec_int ("latency", "Latency",
"Latency to add for smooth demuxing (in ms)", -1,
G_MAXINT, DEFAULT_LATENCY,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
element_class = GST_ELEMENT_CLASS (klass); element_class = GST_ELEMENT_CLASS (klass);
gst_element_class_add_pad_template (element_class, gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&video_template)); gst_static_pad_template_get (&video_template));
@ -455,6 +462,7 @@ gst_ts_demux_init (GstTSDemux * demux)
demux->flowcombiner = gst_flow_combiner_new (); demux->flowcombiner = gst_flow_combiner_new ();
demux->requested_program_number = -1; demux->requested_program_number = -1;
demux->program_number = -1; demux->program_number = -1;
demux->latency = DEFAULT_LATENCY;
gst_ts_demux_reset (base); gst_ts_demux_reset (base);
} }
@ -474,6 +482,9 @@ gst_ts_demux_set_property (GObject * object, guint prop_id,
case PROP_EMIT_STATS: case PROP_EMIT_STATS:
demux->emit_statistics = g_value_get_boolean (value); demux->emit_statistics = g_value_get_boolean (value);
break; break;
case PROP_LATENCY:
demux->latency = g_value_get_int (value);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
} }
@ -492,6 +503,9 @@ gst_ts_demux_get_property (GObject * object, guint prop_id,
case PROP_EMIT_STATS: case PROP_EMIT_STATS:
g_value_set_boolean (value, demux->emit_statistics); g_value_set_boolean (value, demux->emit_statistics);
break; break;
case PROP_LATENCY:
g_value_set_int (value, demux->latency);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
} }
@ -558,6 +572,7 @@ gst_ts_demux_srcpad_query (GstPad * pad, GstObject * parent, GstQuery * query)
if (res) { if (res) {
GstClockTime min_lat, max_lat; GstClockTime min_lat, max_lat;
gboolean live; gboolean live;
gint latency;
/* According to H.222.0 /* According to H.222.0
Annex D.0.3 (System Time Clock recovery in the decoder) Annex D.0.3 (System Time Clock recovery in the decoder)
@ -566,10 +581,13 @@ gst_ts_demux_srcpad_query (GstPad * pad, GstObject * parent, GstQuery * query)
We can end up with an interval of up to 700ms between valid We can end up with an interval of up to 700ms between valid
PTS/DTS. We therefore allow a latency of 700ms for that. PTS/DTS. We therefore allow a latency of 700ms for that.
*/ */
latency = demux->latency;
if (latency < 0)
latency = 700;
gst_query_parse_latency (query, &live, &min_lat, &max_lat); gst_query_parse_latency (query, &live, &min_lat, &max_lat);
min_lat += TS_LATENCY; min_lat += latency * GST_MSECOND;
if (GST_CLOCK_TIME_IS_VALID (max_lat)) if (GST_CLOCK_TIME_IS_VALID (max_lat))
max_lat += TS_LATENCY; max_lat += latency * GST_MSECOND;
gst_query_set_latency (query, live, min_lat, max_lat); gst_query_set_latency (query, live, min_lat, max_lat);
} }
break; break;

View file

@ -76,6 +76,7 @@ struct _GstTSDemux
gint requested_program_number; /* Required program number (ignore:-1) */ gint requested_program_number; /* Required program number (ignore:-1) */
guint program_number; guint program_number;
gboolean emit_statistics; gboolean emit_statistics;
gint latency; /* latency in ms */
/*< private >*/ /*< private >*/
gint program_generation; /* Incremented each time we switch program 0..15 */ gint program_generation; /* Incremented each time we switch program 0..15 */