From f11735c97b672b44c7694ae1c518a40f7cff1a59 Mon Sep 17 00:00:00 2001 From: Jordan Yelloz Date: Mon, 8 Jul 2024 16:42:58 -0600 Subject: [PATCH] tsmux: Adjust byte counter when adjusting bitrate When configured in constant bitrate mode, the muxer computes timing information using the configured bitrate and the byte counter (now = bytes sent / byterate). When an application changes the bitrate in CBR mode during playback, the relationship between bytes sent and bitrate is no longer valid so new timing values will be off by the ratio of the old bitrate to the new bitrate. Furthermore, it will upset the way that padding is generated. pad_stream() works by trying to fit the byte counter to now * byterate. The result is that when decreasing bitrate, the muxer stalls, waiting until the byte counter is in agreement with now * byterate. Also, when increasing bitrate, the padding will spike in volume until the byte counter fits with now * byterate. If the byte counter is scaled by the ratio of new bitrate / old bitrate when adjusting bitrate, then padding is generated in a way that applications would more likely expect. One detail this change doesn't yet address is whether the next PCR will match up optimally with the previous PCR right after the byte counter is scaled. In that case, some correction may be necessary. Also, perhaps the user should be prevented from changing from bitrate=0 to bitrate=nonzero during playback since it's not straightforward how to scale the byte counter in that case. Part-of: --- subprojects/gst-plugins-bad/gst/mpegtsmux/tsmux/tsmux.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/subprojects/gst-plugins-bad/gst/mpegtsmux/tsmux/tsmux.c b/subprojects/gst-plugins-bad/gst/mpegtsmux/tsmux/tsmux.c index 36bd177ad2..c6c5adb023 100644 --- a/subprojects/gst-plugins-bad/gst/mpegtsmux/tsmux/tsmux.c +++ b/subprojects/gst-plugins-bad/gst/mpegtsmux/tsmux/tsmux.c @@ -1929,5 +1929,13 @@ tsmux_write_scte_null (TsMux * mux, TsMuxProgram * program) void tsmux_set_bitrate (TsMux * mux, guint64 bitrate) { + if (bitrate != 0 && mux->bitrate != 0 && mux->n_bytes != 0) { + guint64 new_byte_counter = + gst_util_uint64_scale (mux->n_bytes, bitrate, mux->bitrate); + GST_LOG ("bitrate transition %" G_GUINT64_FORMAT " => %" G_GUINT64_FORMAT + ", adjusting byte counter %" G_GUINT64_FORMAT " => %" G_GUINT64_FORMAT, + mux->bitrate, bitrate, mux->n_bytes, new_byte_counter); + mux->n_bytes = new_byte_counter; + } mux->bitrate = bitrate; }