summaryrefslogtreecommitdiff
path: root/gst/mpegtsmux/tsmux
diff options
context:
space:
mode:
authorMathieu Duponchelle <mathieu@centricular.com>2019-04-22 22:50:07 +0200
committerMathieu Duponchelle <mduponchelle1@gmail.com>2019-05-19 19:40:48 +0000
commit98c98c7c53f51a69b249007a4b9a4f6507874989 (patch)
treeafeb5209ecce6abb943d069863eaab6ea978c3c8 /gst/mpegtsmux/tsmux
parent07235bbf46100caab241fd707a135eccd3a923c4 (diff)
downloadgstreamer-plugins-bad-98c98c7c53f51a69b249007a4b9a4f6507874989.tar.gz
tsmux: Calculate PCR from number of bytes written in CBR mode
Diffstat (limited to 'gst/mpegtsmux/tsmux')
-rw-r--r--gst/mpegtsmux/tsmux/tsmux.c80
1 files changed, 53 insertions, 27 deletions
diff --git a/gst/mpegtsmux/tsmux/tsmux.c b/gst/mpegtsmux/tsmux/tsmux.c
index e94c6808a..f22ce2406 100644
--- a/gst/mpegtsmux/tsmux/tsmux.c
+++ b/gst/mpegtsmux/tsmux/tsmux.c
@@ -796,7 +796,7 @@ tsmux_write_adaptation_field (guint8 * buf,
static gboolean
tsmux_write_ts_header (guint8 * buf, TsMuxPacketInfo * pi,
- guint * payload_len_out, guint * payload_offset_out)
+ guint * payload_len_out, guint * payload_offset_out, guint stream_avail)
{
guint8 *tmp;
guint8 adaptation_flag;
@@ -809,7 +809,7 @@ tsmux_write_ts_header (guint8 * buf, TsMuxPacketInfo * pi,
buf[0] = TSMUX_SYNC_BYTE;
TS_DEBUG ("PID 0x%04x, counter = 0x%01x, %u bytes avail", pi->pid,
- pi->packet_count & 0x0f, pi->stream_avail);
+ pi->packet_count & 0x0f, stream_avail);
/* 3 bits:
* transport_error_indicator
@@ -833,9 +833,9 @@ tsmux_write_ts_header (guint8 * buf, TsMuxPacketInfo * pi,
write_adapt = TRUE;
}
- if (pi->stream_avail < TSMUX_PAYLOAD_LENGTH) {
+ if (stream_avail < TSMUX_PAYLOAD_LENGTH) {
/* Need an adaptation field regardless for stuffing */
- adapt_min_length = TSMUX_PAYLOAD_LENGTH - pi->stream_avail;
+ adapt_min_length = TSMUX_PAYLOAD_LENGTH - stream_avail;
write_adapt = TRUE;
}
@@ -859,13 +859,13 @@ tsmux_write_ts_header (guint8 * buf, TsMuxPacketInfo * pi,
*payload_offset_out = TSMUX_HEADER_LENGTH + adapt_len;
/* Now if we are going to write out some payload, flag that fact */
- if (payload_len > 0 && pi->stream_avail > 0) {
+ if (payload_len > 0 && stream_avail > 0) {
/* Flag the presence of a payload */
adaptation_flag |= 0x10;
/* We must have enough data to fill the payload, or some calculation
* went wrong */
- g_assert (payload_len <= pi->stream_avail);
+ g_assert (payload_len <= stream_avail);
/* Packet with payload, increment the continuity counter */
pi->packet_count++;
@@ -933,7 +933,8 @@ tsmux_section_write_packet (GstMpegtsSectionType * type,
/* Wee need room for a pointer byte */
section->pi.stream_avail++;
- if (!tsmux_write_ts_header (packet, &section->pi, &len, &offset))
+ if (!tsmux_write_ts_header (packet, &section->pi, &len, &offset,
+ section->pi.stream_avail))
goto fail;
/* Write the pointer byte */
@@ -941,7 +942,8 @@ tsmux_section_write_packet (GstMpegtsSectionType * type,
payload_len = len - 1;
} else {
- if (!tsmux_write_ts_header (packet, &section->pi, &len, &offset))
+ if (!tsmux_write_ts_header (packet, &section->pi, &len, &offset,
+ section->pi.stream_avail))
goto fail;
payload_len = len;
}
@@ -1031,7 +1033,7 @@ tsmux_write_null_ts_header (guint8 * buf)
}
static gboolean
-pad_stream (TsMux * mux, TsMuxStream * stream, gint64 cur_ts)
+pad_stream (TsMux * mux, TsMuxStream * stream, gint64 cur_ts, gint64 * cur_pcr)
{
guint64 bitrate;
GstBuffer *buf = NULL;
@@ -1047,6 +1049,11 @@ pad_stream (TsMux * mux, TsMuxStream * stream, gint64 cur_ts)
diff = GST_CLOCK_DIFF (stream->first_ts, cur_ts);
+ *cur_pcr =
+ (CLOCK_BASE - TSMUX_PCR_OFFSET) * 300 +
+ gst_util_uint64_scale (mux->n_bytes * 8, TSMUX_SYS_CLOCK_FREQ,
+ mux->bitrate);
+
if (diff) {
bitrate =
gst_util_uint64_scale (mux->n_bytes * 8, TSMUX_CLOCK_FREQ, diff);
@@ -1063,11 +1070,31 @@ pad_stream (TsMux * mux, TsMuxStream * stream, gint64 cur_ts)
gst_buffer_map (buf, &map, GST_MAP_READ);
- tsmux_write_null_ts_header (map.data);
+ if (stream->next_pcr == -1 || *cur_pcr > stream->next_pcr) {
+ guint payload_len, payload_offs;
+
+ stream->pi.flags |=
+ TSMUX_PACKET_FLAG_ADAPTATION | TSMUX_PACKET_FLAG_WRITE_PCR;
+ stream->pi.pcr = *cur_pcr;
+
+ if (stream->next_pcr == -1)
+ stream->next_pcr =
+ *cur_pcr + TSMUX_SYS_CLOCK_FREQ / TSMUX_DEFAULT_PCR_FREQ;
+ else
+ stream->next_pcr += TSMUX_SYS_CLOCK_FREQ / TSMUX_DEFAULT_PCR_FREQ;
+
+ tsmux_write_ts_header (map.data, &stream->pi, &payload_len,
+ &payload_offs, 0);
+
+ stream->pi.flags &= TSMUX_PACKET_FLAG_PES_FULL_HEADER;
+ } else {
+ tsmux_write_null_ts_header (map.data);
+ *cur_pcr = -1;
+ }
gst_buffer_unmap (buf, &map);
- if (!(ret = tsmux_packet_out (mux, buf, -1)))
+ if (!(ret = tsmux_packet_out (mux, buf, *cur_pcr)))
goto done;
}
} else {
@@ -1115,23 +1142,21 @@ 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);
- }
- /* FIXME: The current PCR needs more careful calculation than just
- * writing a fixed offset */
- if (cur_ts != G_MININT64) {
- /* CLOCK_BASE >= TSMUX_PCR_OFFSET */
- cur_ts += CLOCK_BASE;
- cur_pcr = (cur_ts - TSMUX_PCR_OFFSET) *
- (TSMUX_SYS_CLOCK_FREQ / TSMUX_CLOCK_FREQ);
+ if (mux->bitrate) {
+ if (!pad_stream (mux, stream, cur_ts, &cur_pcr))
+ goto fail;
+ } else {
+ /* FIXME: The current PCR needs more careful calculation than just
+ * writing a fixed offset */
+ if (cur_ts != G_MININT64) {
+ TS_DEBUG ("TS for PCR stream is %" G_GINT64_FORMAT, cur_ts);
+ /* CLOCK_BASE >= TSMUX_PCR_OFFSET */
+ cur_ts += CLOCK_BASE;
+ cur_pcr = (cur_ts - TSMUX_PCR_OFFSET) *
+ (TSMUX_SYS_CLOCK_FREQ / TSMUX_CLOCK_FREQ);
+ }
}
/* Need to decide whether to write a new PCR in this packet */
@@ -1213,7 +1238,8 @@ tsmux_write_stream_packet (TsMux * mux, TsMuxStream * stream)
gst_buffer_map (buf, &map, GST_MAP_READ);
- if (!tsmux_write_ts_header (map.data, pi, &payload_len, &payload_offs))
+ if (!tsmux_write_ts_header (map.data, pi, &payload_len, &payload_offs,
+ pi->stream_avail))
goto fail;