mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-23 15:48:23 +00:00
tsmux: Calculate PCR from number of bytes written in CBR mode
This commit is contained in:
parent
07235bbf46
commit
98c98c7c53
1 changed files with 53 additions and 27 deletions
|
@ -796,7 +796,7 @@ tsmux_write_adaptation_field (guint8 * buf,
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
tsmux_write_ts_header (guint8 * buf, TsMuxPacketInfo * pi,
|
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 *tmp;
|
||||||
guint8 adaptation_flag;
|
guint8 adaptation_flag;
|
||||||
|
@ -809,7 +809,7 @@ tsmux_write_ts_header (guint8 * buf, TsMuxPacketInfo * pi,
|
||||||
buf[0] = TSMUX_SYNC_BYTE;
|
buf[0] = TSMUX_SYNC_BYTE;
|
||||||
|
|
||||||
TS_DEBUG ("PID 0x%04x, counter = 0x%01x, %u bytes avail", pi->pid,
|
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:
|
/* 3 bits:
|
||||||
* transport_error_indicator
|
* transport_error_indicator
|
||||||
|
@ -833,9 +833,9 @@ tsmux_write_ts_header (guint8 * buf, TsMuxPacketInfo * pi,
|
||||||
write_adapt = TRUE;
|
write_adapt = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pi->stream_avail < TSMUX_PAYLOAD_LENGTH) {
|
if (stream_avail < TSMUX_PAYLOAD_LENGTH) {
|
||||||
/* Need an adaptation field regardless for stuffing */
|
/* 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;
|
write_adapt = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -859,13 +859,13 @@ tsmux_write_ts_header (guint8 * buf, TsMuxPacketInfo * pi,
|
||||||
*payload_offset_out = TSMUX_HEADER_LENGTH + adapt_len;
|
*payload_offset_out = TSMUX_HEADER_LENGTH + adapt_len;
|
||||||
|
|
||||||
/* Now if we are going to write out some payload, flag that fact */
|
/* 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 */
|
/* Flag the presence of a payload */
|
||||||
adaptation_flag |= 0x10;
|
adaptation_flag |= 0x10;
|
||||||
|
|
||||||
/* We must have enough data to fill the payload, or some calculation
|
/* We must have enough data to fill the payload, or some calculation
|
||||||
* went wrong */
|
* went wrong */
|
||||||
g_assert (payload_len <= pi->stream_avail);
|
g_assert (payload_len <= stream_avail);
|
||||||
|
|
||||||
/* Packet with payload, increment the continuity counter */
|
/* Packet with payload, increment the continuity counter */
|
||||||
pi->packet_count++;
|
pi->packet_count++;
|
||||||
|
@ -933,7 +933,8 @@ tsmux_section_write_packet (GstMpegtsSectionType * type,
|
||||||
/* Wee need room for a pointer byte */
|
/* Wee need room for a pointer byte */
|
||||||
section->pi.stream_avail++;
|
section->pi.stream_avail++;
|
||||||
|
|
||||||
if (!tsmux_write_ts_header (packet, §ion->pi, &len, &offset))
|
if (!tsmux_write_ts_header (packet, §ion->pi, &len, &offset,
|
||||||
|
section->pi.stream_avail))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* Write the pointer byte */
|
/* Write the pointer byte */
|
||||||
|
@ -941,7 +942,8 @@ tsmux_section_write_packet (GstMpegtsSectionType * type,
|
||||||
payload_len = len - 1;
|
payload_len = len - 1;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (!tsmux_write_ts_header (packet, §ion->pi, &len, &offset))
|
if (!tsmux_write_ts_header (packet, §ion->pi, &len, &offset,
|
||||||
|
section->pi.stream_avail))
|
||||||
goto fail;
|
goto fail;
|
||||||
payload_len = len;
|
payload_len = len;
|
||||||
}
|
}
|
||||||
|
@ -1031,7 +1033,7 @@ tsmux_write_null_ts_header (guint8 * buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
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;
|
guint64 bitrate;
|
||||||
GstBuffer *buf = NULL;
|
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);
|
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) {
|
if (diff) {
|
||||||
bitrate =
|
bitrate =
|
||||||
gst_util_uint64_scale (mux->n_bytes * 8, TSMUX_CLOCK_FREQ, diff);
|
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);
|
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);
|
gst_buffer_unmap (buf, &map);
|
||||||
|
|
||||||
if (!(ret = tsmux_packet_out (mux, buf, -1)))
|
if (!(ret = tsmux_packet_out (mux, buf, *cur_pcr)))
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1115,23 +1142,21 @@ tsmux_write_stream_packet (TsMux * mux, TsMuxStream * stream)
|
||||||
else
|
else
|
||||||
cur_ts = tsmux_stream_get_pts (stream);
|
cur_ts = tsmux_stream_get_pts (stream);
|
||||||
|
|
||||||
if (mux->bitrate) {
|
|
||||||
if (!pad_stream (mux, stream, cur_ts))
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
cur_pcr = 0;
|
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
|
if (mux->bitrate) {
|
||||||
* writing a fixed offset */
|
if (!pad_stream (mux, stream, cur_ts, &cur_pcr))
|
||||||
if (cur_ts != G_MININT64) {
|
goto fail;
|
||||||
/* CLOCK_BASE >= TSMUX_PCR_OFFSET */
|
} else {
|
||||||
cur_ts += CLOCK_BASE;
|
/* FIXME: The current PCR needs more careful calculation than just
|
||||||
cur_pcr = (cur_ts - TSMUX_PCR_OFFSET) *
|
* writing a fixed offset */
|
||||||
(TSMUX_SYS_CLOCK_FREQ / TSMUX_CLOCK_FREQ);
|
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 */
|
/* 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);
|
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;
|
goto fail;
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue