diff options
author | Mathieu Duponchelle <mathieu@centricular.com> | 2019-04-22 22:11:29 +0200 |
---|---|---|
committer | Mathieu Duponchelle <mduponchelle1@gmail.com> | 2019-05-19 19:40:48 +0000 |
commit | 07235bbf46100caab241fd707a135eccd3a923c4 (patch) | |
tree | 797a10aa9c52f8b2eff9197d722b31d39b64765a /gst/mpegtsmux/tsmux | |
parent | 4d53a7ac0974839dc4945e48ed1934d11ddb14f9 (diff) | |
download | gstreamer-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.c | 79 | ||||
-rw-r--r-- | gst/mpegtsmux/tsmux/tsmux.h | 4 | ||||
-rw-r--r-- | gst/mpegtsmux/tsmux/tsmuxcommon.h | 2 | ||||
-rw-r--r-- | gst/mpegtsmux/tsmux/tsmuxstream.c | 2 | ||||
-rw-r--r-- | gst/mpegtsmux/tsmux/tsmuxstream.h | 2 |
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 */ |