[FFmpeg-devel] [PATCH] avformat/mpegtsenc: fix PCR generation intervals
Andreas Håkon
andreas.hakon at protonmail.com
Mon Aug 5 21:40:13 EEST 2019
Hi Marton,
‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On Sunday, 4 de August de 2019 22:30, Marton Balint <cus at passwd.hu> wrote:
> PCR generation was based on counting packets for both CBR and VBR streams.
> Couting packets might have worked for CBR streams (when muxrate was specified)
> but it only took into account the packets of a service (or the packets of the
> PCR stream lately), so even that was problematic for multi program streams.
>
> The new code works on actual PCR for CBR and packet DTS values for VBR streams,
> so the default 20ms PCR retransmission time is now respected for both CBR and
> VBR.
>
I do some tests with this patch and the previous https://patchwork.ffmpeg.org/patch/14210/
And the result is that the repetition rate of PCR is inconsistent: it's never
constant and varies between different PCR streams.
But fortunately I have an idea...
> Signed-off-by: Marton Balint cus at passwd.hu
>
> libavformat/mpegtsenc.c | 60 +++++++++++++++----------------------------------
> tests/ref/lavf/ts | 2 +-
> 2 files changed, 19 insertions(+), 43 deletions(-)
>
> diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
[...]
> @@ -1194,18 +1168,24 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
>
> is_start = 1;
> while (payload_size > 0) {
> + int64_t pcr = -1; /* avoid warning */
> +
> retransmit_si_info(s, force_pat, dts);
> force_pat = 0;
>
> write_pcr = 0;
> - if (ts_st->pcr_packet_period) {
> - if (ts->mux_rate > 1 || is_start) // VBR pcr period is based on frames
> - ts_st->pcr_packet_count++;
> - if (ts_st->pcr_packet_count >=
> - ts_st->pcr_packet_period) {
> - ts_st->pcr_packet_count = 0;
> - write_pcr = 1;
> + if (ts_st->pcr_period) {
> + if (ts->mux_rate > 1) {
> + pcr = get_pcr(ts, s->pb);
> + if (pcr - ts_st->last_pcr >= ts_st->pcr_period)
> + write_pcr = 1;
> + } else if (dts != AV_NOPTS_VALUE) {
> + pcr = (dts - delay) * 300;
> + if (pcr - ts_st->last_pcr >= ts_st->pcr_period && is_start)
> + write_pcr = 1;
> }
> + if (write_pcr)
> + ts_st->last_pcr = FFMAX(pcr - ts_st->pcr_period, ts_st->last_pcr + ts_st->pcr_period);
> }
IMHO, here you return to make the same mistake of the previous code:
only consider one PCR stream. Instead of the "if (ts_st->pcr_period)" it's
required to iterate over all PCR streams and do the corresponding checks.
And if some PCR stream has exceeded the pcr_period limit then enforce to
write an empty TS packet with a PCR mark.
In fact, the root cause is the sequential PES writing on the MPEG-TS muxer.
And this is the reason for my interleaving mux patch:
https://patchwork.ffmpeg.org/patch/13745/
However, until I rebase your code for the interleave mux mode, the PCR
generation of this patch needs to be fixed.
[...]
Regards.
A.H.
---
More information about the ffmpeg-devel
mailing list