summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Schmidt <jan@centricular.com>2021-03-12 18:10:18 +1100
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>2021-03-18 13:57:27 +0000
commit5e4a11bf36b6646021b653855a0a2152be338428 (patch)
tree6cbb2fe25e82f55c1e78629f0fe2996cb15a91ef
parentb7e9e606a97a3e174fc5c791e515fa63df563ff9 (diff)
downloadgstreamer-plugins-bad-5e4a11bf36b6646021b653855a0a2152be338428.tar.gz
mpegtsmux: Don't write PCR until PAT/PMT are output.
Make sure streams start cleanly with a PAT/PMT and defer the first PCR output until after that. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2073>
-rw-r--r--gst/mpegtsmux/tsmux/tsmux.c66
-rw-r--r--gst/mpegtsmux/tsmux/tsmux.h3
2 files changed, 41 insertions, 28 deletions
diff --git a/gst/mpegtsmux/tsmux/tsmux.c b/gst/mpegtsmux/tsmux/tsmux.c
index 186b660d5..3c04c4295 100644
--- a/gst/mpegtsmux/tsmux/tsmux.c
+++ b/gst/mpegtsmux/tsmux/tsmux.c
@@ -812,38 +812,46 @@ tsmux_packet_out (TsMux * mux, GstBuffer * buf, gint64 pcr)
return TRUE;
}
- if (mux->bitrate)
+ if (mux->bitrate) {
GST_BUFFER_PTS (buf) =
gst_util_uint64_scale (mux->n_bytes * 8, GST_SECOND, mux->bitrate);
- if (mux->bitrate && mux->first_pcr_ts != G_MININT64) {
- GList *cur;
-
- for (cur = mux->programs; cur; cur = cur->next) {
- TsMuxProgram *program = (TsMuxProgram *) cur->data;
- TsMuxStream *stream = program->pcr_stream;
- gint64 cur_pcr = get_current_pcr (mux, 0);
- gint64 next_pcr = get_next_pcr (mux, 0);
-
- gint64 new_pcr = write_new_pcr (mux, stream, cur_pcr, next_pcr);
-
- if (new_pcr != -1) {
- GstBuffer *buf = NULL;
- GstMapInfo map;
- guint payload_len, payload_offs;
-
- if (!tsmux_get_buffer (mux, &buf)) {
- goto error;
+ /* Check and insert a PCR observation for each program if needed,
+ * but only for programs that have written their SI at least once,
+ * so the stream starts with PAT/PMT */
+ if (mux->first_pcr_ts != G_MININT64) {
+ GList *cur;
+
+ for (cur = mux->programs; cur; cur = cur->next) {
+ TsMuxProgram *program = (TsMuxProgram *) cur->data;
+ TsMuxStream *stream = program->pcr_stream;
+ gint64 cur_pcr, next_pcr, new_pcr;
+
+ if (!program->wrote_si)
+ continue;
+
+ cur_pcr = get_current_pcr (mux, 0);
+ next_pcr = get_next_pcr (mux, 0);
+ new_pcr = write_new_pcr (mux, stream, cur_pcr, next_pcr);
+
+ if (new_pcr != -1) {
+ GstBuffer *buf = NULL;
+ GstMapInfo map;
+ guint payload_len, payload_offs;
+
+ if (!tsmux_get_buffer (mux, &buf)) {
+ goto error;
+ }
+
+ gst_buffer_map (buf, &map, GST_MAP_READ);
+ tsmux_write_ts_header (mux, map.data, &stream->pi, &payload_len,
+ &payload_offs, 0);
+ gst_buffer_unmap (buf, &map);
+
+ stream->pi.flags &= TSMUX_PACKET_FLAG_PES_FULL_HEADER;
+ if (!tsmux_packet_out (mux, buf, new_pcr))
+ goto error;
}
-
- gst_buffer_map (buf, &map, GST_MAP_READ);
- tsmux_write_ts_header (mux, map.data, &stream->pi, &payload_len,
- &payload_offs, 0);
- gst_buffer_unmap (buf, &map);
-
- stream->pi.flags &= TSMUX_PACKET_FLAG_PES_FULL_HEADER;
- if (!tsmux_packet_out (mux, buf, new_pcr))
- goto error;
}
}
}
@@ -1452,6 +1460,8 @@ rewrite_si (TsMux * mux, gint64 cur_ts)
next_pcr = get_current_pcr (mux, cur_ts);
}
}
+
+ program->wrote_si = TRUE;
}
return TRUE;
diff --git a/gst/mpegtsmux/tsmux/tsmux.h b/gst/mpegtsmux/tsmux/tsmux.h
index 9f067a342..df2a4676a 100644
--- a/gst/mpegtsmux/tsmux/tsmux.h
+++ b/gst/mpegtsmux/tsmux/tsmux.h
@@ -111,6 +111,9 @@ struct TsMuxSection {
/* Information for the streams associated with one program */
struct TsMuxProgram {
+ /* TRUE if the SI has been written at least once */
+ gboolean wrote_si;
+
TsMuxSection pmt;
/* PMT version */
guint8 pmt_version;