summaryrefslogtreecommitdiff
path: root/subprojects
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2024-09-13 10:55:03 +0300
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>2024-10-01 13:20:18 +0000
commit12b434ae9d1f2645d8e317771f4bae14e74333d6 (patch)
treedd9d401075b439dac68449f7f0967df53e471b56 /subprojects
parent945a7bdfc412fb36d09c0e7fdbd60e369730b1a2 (diff)
matroskamux: Add support for latency timeouts in live pipelinesHEADmain
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7510>
Diffstat (limited to 'subprojects')
-rw-r--r--subprojects/gst-plugins-good/gst/matroska/matroska-mux.c74
-rw-r--r--subprojects/gst-plugins-good/gst/matroska/matroska-mux.h1
2 files changed, 63 insertions, 12 deletions
diff --git a/subprojects/gst-plugins-good/gst/matroska/matroska-mux.c b/subprojects/gst-plugins-good/gst/matroska/matroska-mux.c
index fab9b29656..0415bbe09d 100644
--- a/subprojects/gst-plugins-good/gst/matroska/matroska-mux.c
+++ b/subprojects/gst-plugins-good/gst/matroska/matroska-mux.c
@@ -239,6 +239,7 @@ static gboolean gst_matroska_mux_src_event (GstAggregator * agg,
static gboolean gst_matroska_mux_stop (GstAggregator * agg);
static GstBuffer *gst_matroska_mux_clip (GstAggregator * agg,
GstAggregatorPad * agg_pad, GstBuffer * buffer);
+static GstClockTime gst_matroska_mux_get_next_time (GstAggregator * agg);
static GstPad *gst_matroska_mux_request_new_pad (GstElement * element,
GstPadTemplate * templ, const gchar * name, const GstCaps * caps);
@@ -415,6 +416,8 @@ gst_matroska_mux_class_init (GstMatroskaMuxClass * klass)
GST_DEBUG_FUNCPTR (gst_matroska_mux_sink_event);
gstaggregator_class->src_event =
GST_DEBUG_FUNCPTR (gst_matroska_mux_src_event);
+ gstaggregator_class->get_next_time =
+ GST_DEBUG_FUNCPTR (gst_matroska_mux_get_next_time);
parent_class = g_type_class_peek_parent (klass);
@@ -662,6 +665,7 @@ gst_matroska_mux_stop (GstAggregator * agg)
/* reset timers */
mux->duration = 0;
+ mux->last_pos = 0;
/* reset cluster */
mux->cluster = 0;
@@ -701,6 +705,20 @@ gst_matroska_mux_src_event (GstAggregator * agg, GstEvent * event)
return GST_AGGREGATOR_CLASS (parent_class)->src_event (agg, event);
}
+static GstClockTime
+gst_matroska_mux_get_next_time (GstAggregator * agg)
+{
+ GstMatroskaMux *mux = GST_MATROSKA_MUX (agg);
+ GstSegment segment;
+ GstClockTime next_time;
+
+ gst_segment_init (&segment, GST_FORMAT_TIME);
+ next_time =
+ gst_segment_to_running_time (&segment, GST_FORMAT_TIME, mux->last_pos);
+
+ return next_time;
+}
+
static void
gst_matroska_mux_free_codec_priv (GstMatroskaTrackContext * context)
{
@@ -4174,7 +4192,7 @@ gst_matroska_mux_find_best_pad (GstMatroskaMux * mux, gboolean timeout)
buffer = gst_aggregator_pad_peek_buffer (GST_AGGREGATOR_PAD (mux_pad));
if (!buffer) {
- if (!GST_PAD_IS_EOS (mux_pad)) {
+ if (!timeout && !GST_PAD_IS_EOS (mux_pad)) {
best = NULL;
best_time = GST_CLOCK_TIME_NONE;
break;
@@ -4203,11 +4221,31 @@ gst_matroska_mux_find_best_pad (GstMatroskaMux * mux, gboolean timeout)
return best;
}
+static gboolean
+gst_matroska_mux_all_pads_eos (GstMatroskaMux * mux)
+{
+ GList *l;
+
+ GST_OBJECT_LOCK (mux);
+ for (l = GST_ELEMENT_CAST (mux)->sinkpads; l; l = l->next) {
+ GstMatroskaMuxPad *pad = GST_MATROSKA_MUX_PAD (l->data);
+
+ if (gst_aggregator_pad_has_buffer (GST_AGGREGATOR_PAD (pad))
+ || !gst_aggregator_pad_is_eos (GST_AGGREGATOR_PAD (pad))) {
+ GST_OBJECT_UNLOCK (mux);
+ return FALSE;
+ }
+ }
+ GST_OBJECT_UNLOCK (mux);
+
+ return TRUE;
+}
+
static GstFlowReturn
gst_matroska_mux_aggregate (GstAggregator * agg, gboolean timeout)
{
GstMatroskaMux *mux = GST_MATROSKA_MUX (agg);
- GstClockTime buffer_timestamp;
+ GstClockTime buffer_timestamp, end_ts = GST_CLOCK_TIME_NONE;
GstEbmlWrite *ebml = mux->ebml_write;
GstMatroskaMuxPad *best = NULL;
GstBuffer *buf;
@@ -4229,15 +4267,20 @@ gst_matroska_mux_aggregate (GstAggregator * agg, gboolean timeout)
best = gst_matroska_mux_find_best_pad (mux, timeout);
- /* if there is no best pad, we have reached EOS */
+ /* if there is no best pad, we have reached EOS or timed out without any
+ * buffers */
if (best == NULL) {
- GST_DEBUG_OBJECT (mux, "No best pad. Finishing...");
- if (!mux->ebml_write->streamable) {
- gst_matroska_mux_finish (mux);
+ if (gst_matroska_mux_all_pads_eos (mux)) {
+ GST_DEBUG_OBJECT (mux, "All pads EOS. Finishing...");
+ if (!mux->ebml_write->streamable) {
+ gst_matroska_mux_finish (mux);
+ } else {
+ GST_DEBUG_OBJECT (mux, "... but streamable, nothing to finish");
+ }
+ ret = GST_FLOW_EOS;
} else {
- GST_DEBUG_OBJECT (mux, "... but streamable, nothing to finish");
+ ret = GST_AGGREGATOR_FLOW_NEED_DATA;
}
- ret = GST_FLOW_EOS;
goto exit;
}
@@ -4271,8 +4314,7 @@ gst_matroska_mux_aggregate (GstAggregator * agg, gboolean timeout)
/* make note of first and last encountered timestamps, so we can calculate
* the actual duration later when we send an updated header on eos */
if (GST_CLOCK_TIME_IS_VALID (buffer_timestamp)) {
- GstClockTime start_ts = buffer_timestamp;
- GstClockTime end_ts = start_ts;
+ end_ts = buffer_timestamp;
if (GST_BUFFER_DURATION_IS_VALID (buf))
end_ts += GST_BUFFER_DURATION (buf);
@@ -4283,8 +4325,8 @@ gst_matroska_mux_aggregate (GstAggregator * agg, gboolean timeout)
best->end_ts = end_ts;
if (G_UNLIKELY (best->start_ts == GST_CLOCK_TIME_NONE ||
- start_ts < best->start_ts))
- best->start_ts = start_ts;
+ buffer_timestamp < best->start_ts))
+ best->start_ts = buffer_timestamp;
}
if ((gst_buffer_get_size (buf) == 0 &&
@@ -4297,6 +4339,14 @@ gst_matroska_mux_aggregate (GstAggregator * agg, gboolean timeout)
ret = gst_matroska_mux_write_data (mux, best, buf);
}
+ if (GST_CLOCK_TIME_IS_VALID (buffer_timestamp)) {
+ if (GST_CLOCK_TIME_IS_VALID (end_ts)
+ && mux->last_pos < end_ts)
+ mux->last_pos = end_ts;
+ else if (mux->last_pos < buffer_timestamp)
+ mux->last_pos = buffer_timestamp;
+ }
+
exit:
gst_clear_object (&best);
diff --git a/subprojects/gst-plugins-good/gst/matroska/matroska-mux.h b/subprojects/gst-plugins-good/gst/matroska/matroska-mux.h
index 9545adbcb0..c9a36f4f61 100644
--- a/subprojects/gst-plugins-good/gst/matroska/matroska-mux.h
+++ b/subprojects/gst-plugins-good/gst/matroska/matroska-mux.h
@@ -126,6 +126,7 @@ struct _GstMatroskaMux {
guint64 earliest_time;
/* length, position (time, ns) */
guint64 duration;
+ GstClockTime last_pos;
/* byte-positions of master-elements (for replacing contents) */
guint64 segment_pos,