On Fri, 17 Jan 2025, 21:32 Romain Beauxis, <romain.beau...@gmail.com> wrote:

> Le ven. 17 janv. 2025 à 08:32, Kieran Kunhya
> <kieran...@googlemail.com> a écrit :
> >
> > On Fri, Jan 17, 2025 at 2:24 PM Kieran Kunhya <kieran...@googlemail.com>
> wrote:
> > >
> > > On Fri, Jan 17, 2025 at 2:00 PM Romain Beauxis <
> romain.beau...@gmail.com> wrote:
> > > >
> > > > Hi,
> > > >
> > > > Le jeu. 16 janv. 2025 à 16:40, Kieran Kunhya
> > > > <kieran...@googlemail.com> a écrit :
> > > > >
> > > > > On Thu, Jan 16, 2025 at 9:35 PM Romain Beauxis <
> romain.beau...@gmail.com> wrote:
> > > > > >
> > > > > > Le jeu. 16 janv. 2025 à 14:48, Kieran Kunhya
> > > > > > <kieran...@googlemail.com> a écrit :
> > > > > > >
> > > > > > > On Thu, 16 Jan 2025, 20:15 Romain Beauxis, <
> romain.beau...@gmail.com> wrote:
> > > > > > >>
> > > > > > >> This patch implements the decoding logic for the FEC error-
> > > > > > >> correction method described in the Pro-MPEG CoP #3-R2 FEC[1]
> > > > > > >>
> > > > > > >> We are still in the process of testing this patch with our
> encoders but
> > > > > > >> I wanted to send it now in case it could use some early
> review.
> > > > > > >>
> > > > > > >> The code seems clean enough and straight forward:
> > > > > > >
> > > > > > >
> > > > > > > As someone who wrote an FEC receiver in Upipe, I'm surprised
> to see the word "straight forward" and FEC used in the same sentence. The
> Upipe implementation (which was never merged) is extremely messy and
> complex and commercial implementations are even worse as I understand.
> There are tons of edge cases.
> > > > > >
> > > > > > Yes, you're right! What I meant by straight forward is that, in
> my
> > > > > > experience, in the absence of a specific heuristics, the most
> simple
> > > > > > and elegant solution is usually the best, at least to make sure
> the
> > > > > > code is easy to read and to improve on later.
> > > > >
> > > > > This is not academia. FEC is about maximising error recovery and
> there
> > > > > are tons of edge cases to create something that works 24/7.
> > > > >
> > > > > > I should have also said that I'm hoping that this implementation
> is an
> > > > > > initial one that provides the functionality for the most "simple"
> > > > > > situations and that could be improved later.
> > > > > >
> > > > > > > The biggest question I have, is how do you decide to schedule
> packets? In the FEC spec, the incoming streams are CBR so the matrix
> duration is fixed. So if there is packet loss you know when to schedule the
> output packets because the latency is fixed. But in FFmpeg you don't know
> the incoming streams are CBR, nor do you have a concept of time. Min and
> max packets is complete guesswork in a VBR stream and the code takes a
> bursty stream and makes it even more bursty. And you of course destroy the
> CBR nature of a valid FEC stream.
> > > > > > >
> > > > > > > The other thing that's difficult is handling a change in
> stream without causing an infinite loop and keeping FEC behaviour
> Heuristics are needed for this.
> > > > > > >
> > > > > > > It's not clear from your code how you handle the matrix
> recursion. i.e the fact you recovered one packet allows you to rerun the
> recovery and potentially recover more from a different column/row.
> > > > > >
> > > > > > The way the algorithm works is:
> > > > > > * Start by buffering an initial amount of packets
> > > > >
> > > > > But you have packet loss so this number represents a variable
> amount of time.
> > > > >
> > > > > > * Read all available FEC packets on each RTP packet read,
> keeping a
> > > > > > max number on each axis
> > > > > > * On first missing packet, keep reading additional RTP packets
> and:
> > > > > >   - Try to reconstruct using the packet row if available
> > > > > >   - Or else, try to reconstruct using the packet column if
> available
> > > > > >   - Or else, try to reconstruct using the whole FEC matrix if
> both are available
> > > > > >
> > > > > > In this matrix reconstruction phase, we keep looping on the rows
> and
> > > > > > columns of the matrix while at least one packet is
> reconstructed. We
> > > > > > also return immediately if the missing packet has been
> reconstructed.
> > > > > >
> > > > > > If the packet cannot be reconstructed, we keep reading packets
> and
> > > > > > trying this algorithm. When the max number of packets is
> reached, we
> > > > > > consider this packet unrecoverable.
> > > > >
> > > > > What about out of order packets?
> > > > >
> > > > > > If you adjust the max number of packets well, this makes sure
> that we
> > > > > > (optimistically) keep one FEC matrix forward from the packet.
> > > > > >
> > > > > > When a packet is returned, we look at the next packet's
> corresponding
> > > > > > FEC row and column packets. If we have both, we know exactly the
> index
> > > > > > of the first packet in the current packet's FEC matrix and we
> drop all
> > > > > > ones before that (RTP and FEC). Otherwise, we keep a whole
> column x
> > > > > > row matrix before the packet.
> > > > >
> > > > > So this basically bursts packets because you don't account for
> packet
> > > > > loss in your buffered packet sizes, nor CBR vs VBR.
> > > > > As I said, if you stop and start the encoder this implementation
> will
> > > > > almost certainly infinite loop and/or crash.
> > > > >
> > > > > > > I also question the need for FEC in 2025. I am happy to see
> this awful protocol gone and am not sure maintaining something like this is
> possible in FFmpeg apart from use cases where latency doesn't matter (so
> why use FEC?).
> > > > > >
> > > > > > The Radio France people have a real problem with packet loss in
> their
> > > > > > RTP streams.
> > > > > >
> > > > > > The rate of packet loss seems to be low enough so that this
> > > > > > implementation would work just fine.
> > > > >
> > > > > Yes but FFmpeg code needs to work in the real world, not just for
> your
> > > > > one customer.
> > > > >
> > > > > > Their hardware encoders have support for FEC encoding so this
> seems
> > > > > > like a real use and benefit right there.
> > > > >
> > > > > There are so much more modern technologies that are vastly easier
> to
> > > > > implement. We have learnt in the last twenty years.
> > > > >
> > > > > Have you tested this implementation with iptables or tc? You'll see
> > > > > it's very difficult to create a stable implementation that doesn't
> > > > > infinite loop as well as survives an encoder restart.
> > > > > I would suggest putting this on a real domestic internet connection
> > > > > where it's very hard to create a stable implementation.
> > > >
> > > > Hi,
> > > >
> > > > While I appreciate your feedback, I wonder about the need to be
> > > > combative like I perceive here.
> > >
> > > Because in the end writing something for your simple case and
> > > disappearing, FFmpeg will get the blame for things not being good.
> > > Same with FFmpeg supporting complex protocols WebRTC, SDR etc etc.
> > >
> > > >
> > > > At the end of the day, we are looking at a probabilistic problem
> > > > (connectivity issues).
> > > >
> > > > Just like the problem, the solution is probabilistic by nature. In
> > > > some cases, it will be able to recover some packets but. for some, it
> > > > will not.
> > > >
> > > > Even if it does not cover all corner cases, this implementation does
> help.
> > > >
> > > > I have tested it with stimulated network issues and found it to be
> > > > able to restore most packets event at 10 or 20% packet drops.
> > > >
> > > > I have also tested it with a bad local broadband.
> > > >
> > > > We plan on testing it more with a concrete problem and hardware
> encoders.
> > > >
> > > > In my experience, experienced software engineer thrive to propose
> dead
> > > > simple code that is good enough to solve the problems that it
> > > > addresses in most cases.
> > >
> > > Your code is honestly way too simplistic for an FEC implementation.
> > > There is a reason other implementations are much more complex.
> > > You have variable latency (user chooses the buffer size by hand,
> > > seriously...), create burstiness, likely infinite loop with an encoder
> > > restart etc.
> > >
> > > Writing a network protocol is about making it as tolerant to the real
> > > world as possible where all sorts of things happen.
> > >
> > > > Also, interfacing with legacy systems is at the core of what we do
> > > > because it does solve real world problems. This project has plenty of
> > > > support for legacy systems.
> > > >
> > > > I will address the encoder restart, thank you for pointing this out.
> I
> > > > imagine that the SSRC can be used to detect a new stream and
> > > > bump/reset packets indexes.
> > >
> > > SSRC is mandated to be 0 so it can't be used.
> > >
> > > Regards,
> > > Kieran Kunhya
> >
> > I would seriously look at a sophisticated FEC implementation that
> > doesn't require the user to input the matrix size, has a low and
> > constant latency, handles reordered packets and is tolerant to encoder
> > restarts:
> > https://github.com/Upipe/upipe/blob/master/lib/upipe-ts/upipe_rtp_fec.c
>
> I'm just getting to look at that.
>
> Is the ffmpeg RTP input currently supposed to recover from an encoder
> restart?
>
> I did:
> * Start a RTP output:
>
> ffmpeg -i ... rtp://...
>
> * Start a RTP input reading from the input:
>
> ffmpeg -i rtp://... ...
>
> * Stop and start the RTP input process
>
> After that, the running ffmpeg instance keeps dropping packets:
>
> [rtp @ 0x14a804200] RTP: dropping old packet received too late0.215x
>     Last message repeated 7 times
>
> If ffmpeg RTP input is not able to recover from an encoder restart, I
> don't think adding support for that in the FEC decoder will help.
>
> -- Romain
>

There you go, the only way to recover from real world issues is to use
heuristics...

Kieran

>
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Reply via email to