summaryrefslogtreecommitdiff
path: root/gst/mpegtsmux/tsmux
diff options
context:
space:
mode:
authorMathieu Duponchelle <mathieu@centricular.com>2019-04-22 22:11:29 +0200
committerMathieu Duponchelle <mduponchelle1@gmail.com>2019-05-19 19:40:48 +0000
commit07235bbf46100caab241fd707a135eccd3a923c4 (patch)
tree797a10aa9c52f8b2eff9197d722b31d39b64765a /gst/mpegtsmux/tsmux
parent4d53a7ac0974839dc4945e48ed1934d11ddb14f9 (diff)
downloadgstreamer-plugins-bad-07235bbf46100caab241fd707a135eccd3a923c4.tar.gz
mpegtsmux: Expose bitrate property
This allows outputting a Transport Stream with a constant bitrate, by inserting null packets.
Diffstat (limited to 'gst/mpegtsmux/tsmux')
-rw-r--r--gst/mpegtsmux/tsmux/tsmux.c79
-rw-r--r--gst/mpegtsmux/tsmux/tsmux.h4
-rw-r--r--gst/mpegtsmux/tsmux/tsmuxcommon.h2
-rw-r--r--gst/mpegtsmux/tsmux/tsmuxstream.c2
-rw-r--r--gst/mpegtsmux/tsmux/tsmuxstream.h2
5 files changed, 87 insertions, 2 deletions
diff --git a/gst/mpegtsmux/tsmux/tsmux.c b/gst/mpegtsmux/tsmux/tsmux.c
index 0f09e4d44..e94c6808a 100644
--- a/gst/mpegtsmux/tsmux/tsmux.c
+++ b/gst/mpegtsmux/tsmux/tsmux.c
@@ -634,6 +634,8 @@ tsmux_packet_out (TsMux * mux, GstBuffer * buf, gint64 pcr)
return TRUE;
}
+ mux->n_bytes += gst_buffer_get_size (buf);
+
return mux->write_func (buf, mux->write_func_data, pcr);
}
@@ -1019,6 +1021,67 @@ tsmux_write_si (TsMux * mux)
}
+static void
+tsmux_write_null_ts_header (guint8 * buf)
+{
+ *buf++ = TSMUX_SYNC_BYTE;
+ *buf++ = 0x1f;
+ *buf++ = 0xff;
+ *buf++ = 0x10;
+}
+
+static gboolean
+pad_stream (TsMux * mux, TsMuxStream * stream, gint64 cur_ts)
+{
+ guint64 bitrate;
+ GstBuffer *buf = NULL;
+ GstMapInfo map;
+ gboolean ret = TRUE;
+
+ do {
+ if (GST_CLOCK_STIME_IS_VALID (cur_ts)) {
+ GstClockTimeDiff diff;
+
+ if (!GST_CLOCK_STIME_IS_VALID (stream->first_ts))
+ stream->first_ts = cur_ts;
+
+ diff = GST_CLOCK_DIFF (stream->first_ts, cur_ts);
+
+ if (diff) {
+ bitrate =
+ gst_util_uint64_scale (mux->n_bytes * 8, TSMUX_CLOCK_FREQ, diff);
+
+ GST_LOG ("Transport stream bitrate: %" G_GUINT64_FORMAT, bitrate);
+
+ if (bitrate < mux->bitrate) {
+ GST_LOG_OBJECT (mux, "Padding transport stream");
+
+ if (!tsmux_get_buffer (mux, &buf)) {
+ ret = FALSE;
+ goto done;
+ }
+
+ gst_buffer_map (buf, &map, GST_MAP_READ);
+
+ tsmux_write_null_ts_header (map.data);
+
+ gst_buffer_unmap (buf, &map);
+
+ if (!(ret = tsmux_packet_out (mux, buf, -1)))
+ goto done;
+ }
+ } else {
+ break;
+ }
+ } else {
+ break;
+ }
+ } while (bitrate < mux->bitrate);
+
+done:
+ return ret;
+}
+
/**
* tsmux_write_stream_packet:
* @mux: a #TsMux
@@ -1052,6 +1115,11 @@ tsmux_write_stream_packet (TsMux * mux, TsMuxStream * stream)
else
cur_ts = tsmux_stream_get_pts (stream);
+ if (mux->bitrate) {
+ if (!pad_stream (mux, stream, cur_ts))
+ goto fail;
+ }
+
cur_pcr = 0;
if (cur_ts != G_MININT64) {
TS_DEBUG ("TS for PCR stream is %" G_GINT64_FORMAT, cur_ts);
@@ -1165,9 +1233,10 @@ tsmux_write_stream_packet (TsMux * mux, TsMuxStream * stream)
/* ERRORS */
fail:
{
- gst_buffer_unmap (buf, &map);
- if (buf)
+ if (buf) {
+ gst_buffer_unmap (buf, &map);
gst_buffer_unref (buf);
+ }
return FALSE;
}
}
@@ -1312,3 +1381,9 @@ tsmux_write_pmt (TsMux * mux, TsMuxProgram * program)
return tsmux_section_write_packet (GINT_TO_POINTER (GST_MPEGTS_SECTION_PMT),
&program->pmt, mux);
}
+
+void
+tsmux_set_bitrate (TsMux * mux, guint64 bitrate)
+{
+ mux->bitrate = bitrate;
+}
diff --git a/gst/mpegtsmux/tsmux/tsmux.h b/gst/mpegtsmux/tsmux/tsmux.h
index 11a1480bb..a8da29b7f 100644
--- a/gst/mpegtsmux/tsmux/tsmux.h
+++ b/gst/mpegtsmux/tsmux/tsmux.h
@@ -178,6 +178,9 @@ struct TsMux {
/* scratch space for writing ES_info descriptors */
guint8 es_info_buf[TSMUX_MAX_ES_INFO_LENGTH];
+
+ guint64 bitrate;
+ guint64 n_bytes;
};
/* create/free new muxer session */
@@ -191,6 +194,7 @@ void tsmux_set_pat_interval (TsMux *mux, guint interval);
guint tsmux_get_pat_interval (TsMux *mux);
void tsmux_resend_pat (TsMux *mux);
guint16 tsmux_get_new_pid (TsMux *mux);
+void tsmux_set_bitrate (TsMux *mux, guint64 bitrate);
/* pid/program management */
TsMuxProgram * tsmux_program_new (TsMux *mux, gint prog_id);
diff --git a/gst/mpegtsmux/tsmux/tsmuxcommon.h b/gst/mpegtsmux/tsmux/tsmuxcommon.h
index 6d5e87fd5..7121a299f 100644
--- a/gst/mpegtsmux/tsmux/tsmuxcommon.h
+++ b/gst/mpegtsmux/tsmux/tsmuxcommon.h
@@ -121,6 +121,8 @@ G_BEGIN_DECLS
#define TSMUX_DEFAULT_PMT_INTERVAL (TSMUX_CLOCK_FREQ / 10)
/* SI interval (1/10th sec) */
#define TSMUX_DEFAULT_SI_INTERVAL (TSMUX_CLOCK_FREQ / 10)
+/* Bitrate (bits per second) */
+#define TSMUX_DEFAULT_BITRATE 0
typedef struct TsMuxPacketInfo TsMuxPacketInfo;
typedef struct TsMuxProgram TsMuxProgram;
diff --git a/gst/mpegtsmux/tsmux/tsmuxstream.c b/gst/mpegtsmux/tsmux/tsmuxstream.c
index b6c975b0e..7945fc0f9 100644
--- a/gst/mpegtsmux/tsmux/tsmuxstream.c
+++ b/gst/mpegtsmux/tsmux/tsmuxstream.c
@@ -224,6 +224,8 @@ tsmux_stream_new (guint16 pid, TsMuxStreamType stream_type)
break;
}
+ stream->first_ts = GST_CLOCK_STIME_NONE;
+
stream->last_pts = GST_CLOCK_STIME_NONE;
stream->last_dts = GST_CLOCK_STIME_NONE;
diff --git a/gst/mpegtsmux/tsmux/tsmuxstream.h b/gst/mpegtsmux/tsmux/tsmuxstream.h
index 5234c489e..3b160207e 100644
--- a/gst/mpegtsmux/tsmux/tsmuxstream.h
+++ b/gst/mpegtsmux/tsmux/tsmuxstream.h
@@ -197,6 +197,8 @@ struct TsMuxStream {
gint64 last_dts;
gint64 last_pts;
+ gint64 first_ts;
+
/* count of programs using this as PCR */
gint pcr_ref;
/* Next time PCR should be written */